HBuilderX

HBuilderX

极客开发工具
uni-app

uni-app

开发一次,多端覆盖
uniCloud

uniCloud

云开发平台
HTML5+

HTML5+

增强HTML5的功能体验
MUI

MUI

上万Star的前端框架

iOS创建最精简离线打包工程

离线打包 iOS SDK

ios创建最精简离线打包工程
注意:如果离线打包的是uni-app项目 请点击进入查看如何配置

1 打开Xcode,创建新工程,选择“Single View Application”

2 添加创建工程的名称(注意:最好不要填中文或特殊字符)

3 复制HBuilder-Hello工程的delegate和Controller文件覆盖新创建工程的相应文件

4 拷贝以下文件到新创建工程目录下

iOSSDK/SDK/Bundles/PandoraApi.bundle
iOSSDK/SDK/control.xml
iOSSDK/SDK/Libs/liblibPDRCore.a
iOSSDK/SDK/Libs/libcoreSupport.a
iOSSDK/SDK/Libs/liblibUI.a

5 添加刚才拷贝的文件到工程内

6 拷贝IOS-SDK/SDK/inc目录到新创建工程目录下,并添加到工程内

7 点击Project->TARGETS->Build Settings搜索“Other Linker Flags”,双击搜索到的项双击,在弹出框内添加想“-ObjC”

8 点击Projcet->General->Linked Frameworks and Libraries 添加系统库到工程

系统库
JavaScriptCore.framework
WebKit.framework
CoreTelephony.framework
MobileCoreServices.framework
SystemConfiguration.framework
MediaPlayer.framework
AudioToolbox.framework
Security.framework
QuartzCore.framework
CFNetwork.framework
Foundation.framework
CoreFoundation.framework
CoreGraphics.framework
UIKit.framework
QuickLook.framework
libc++.tbd
libxml2.tbd
libz.tbd
libsqlite3.0.tbd
ImageIO.framework
CoreText.framework
Storekit.framework
UserNotifications 并设置为Optianal

9 点击Project->TARGETS->Build Settings搜索“ARC”,修改"Objective-C Automatic Reference Counting"项的值为"NO", 如果希望使用ARC则需要修改相应的内存管理代码。

10 修改头文件搜索路径

点击Project->TARGETS->Build Settings搜索"Header Search Paths",
双击搜索到的"Header Search Paths"项,将工程目录下的inc目录拖到打开的下拉框

11 修改静态库搜索路径

点击Project->TARGETS->Build Settings搜索"Library Search Paths",
如果"Library Search Paths"项下有值则不需要处理,
如果没有值则双击搜索到的"Library Search Paths"项,将工程目录下的libs目录(静态库所在目录)拖到打开的下拉框

12 修改BitCode

点击Project->TARGETS->Build Settings搜索BitCode
将Enable Bitcode项的值改成 ‘NO’

13 添加Web应用到工程

在工程目录下创建目录”Pandora->apps->[APPID]->www“目录,并将Web应用拷贝到www(小写字母)目录下
APPID为要加入到工程应用mainfest.json文件
添加Pandora目录到工程中

添加后会弹出选择类型框,选择”Create Folder References“

添加后工程内的Pandora目录为蓝色

14 修改control.xml文件

修改control.xml文件的appid节点值为mainfest.json文件的id节点下内容,appver节点内容修改为manifest.json文件的version->name节点下内容

如以上三图红圈标记位置都要一致

15 设置应用的图标

点击project->target->General->App Icons and Launch Images->App Icons Source项右侧小箭头

在新开页面根据提示将对应尺寸的应用图标拖入到虚线框中即可

16 设置应用的splash图片

拷贝HBuider-Hello工程的info.plist文件的UILaunchImages节点到新工程info.plist文件,同时拷贝HBuilder-Hello工程下的splash目录到新工程目录下并将其添加到新工程中
根据图片的尺寸逐个替换splash图片,注意文件名不能修改

17 设置应用显示的应用名

点击project->target->General->Identity->Display Name修改应用的显示名称

18 修改info.plist文件,添加App Transport Security Settings类型为Dictionary,在该项下添加Allow Arbitrary Loads项类型为Boolean,值为YES

IOS 10 需要在info.plist文件中添加隐私权限配置

运行时如果提示“打包时未添加XXX模块”,(非中文提示时需要配置国际化),请参考SDK/Feature-ios.xls文件,查找对应插件名需要引入的5+库文件和系统库文件,添加到工程即可

Android创建最精简离线打包工程

继续阅读 »

ios创建最精简离线打包工程
注意:如果离线打包的是uni-app项目 请点击进入查看如何配置

1 打开Xcode,创建新工程,选择“Single View Application”

2 添加创建工程的名称(注意:最好不要填中文或特殊字符)

3 复制HBuilder-Hello工程的delegate和Controller文件覆盖新创建工程的相应文件

4 拷贝以下文件到新创建工程目录下

iOSSDK/SDK/Bundles/PandoraApi.bundle
iOSSDK/SDK/control.xml
iOSSDK/SDK/Libs/liblibPDRCore.a
iOSSDK/SDK/Libs/libcoreSupport.a
iOSSDK/SDK/Libs/liblibUI.a

5 添加刚才拷贝的文件到工程内

6 拷贝IOS-SDK/SDK/inc目录到新创建工程目录下,并添加到工程内

7 点击Project->TARGETS->Build Settings搜索“Other Linker Flags”,双击搜索到的项双击,在弹出框内添加想“-ObjC”

8 点击Projcet->General->Linked Frameworks and Libraries 添加系统库到工程

系统库
JavaScriptCore.framework
WebKit.framework
CoreTelephony.framework
MobileCoreServices.framework
SystemConfiguration.framework
MediaPlayer.framework
AudioToolbox.framework
Security.framework
QuartzCore.framework
CFNetwork.framework
Foundation.framework
CoreFoundation.framework
CoreGraphics.framework
UIKit.framework
QuickLook.framework
libc++.tbd
libxml2.tbd
libz.tbd
libsqlite3.0.tbd
ImageIO.framework
CoreText.framework
Storekit.framework
UserNotifications 并设置为Optianal

9 点击Project->TARGETS->Build Settings搜索“ARC”,修改"Objective-C Automatic Reference Counting"项的值为"NO", 如果希望使用ARC则需要修改相应的内存管理代码。

10 修改头文件搜索路径

点击Project->TARGETS->Build Settings搜索"Header Search Paths",
双击搜索到的"Header Search Paths"项,将工程目录下的inc目录拖到打开的下拉框

11 修改静态库搜索路径

点击Project->TARGETS->Build Settings搜索"Library Search Paths",
如果"Library Search Paths"项下有值则不需要处理,
如果没有值则双击搜索到的"Library Search Paths"项,将工程目录下的libs目录(静态库所在目录)拖到打开的下拉框

12 修改BitCode

点击Project->TARGETS->Build Settings搜索BitCode
将Enable Bitcode项的值改成 ‘NO’

13 添加Web应用到工程

在工程目录下创建目录”Pandora->apps->[APPID]->www“目录,并将Web应用拷贝到www(小写字母)目录下
APPID为要加入到工程应用mainfest.json文件
添加Pandora目录到工程中

添加后会弹出选择类型框,选择”Create Folder References“

添加后工程内的Pandora目录为蓝色

14 修改control.xml文件

修改control.xml文件的appid节点值为mainfest.json文件的id节点下内容,appver节点内容修改为manifest.json文件的version->name节点下内容

如以上三图红圈标记位置都要一致

15 设置应用的图标

点击project->target->General->App Icons and Launch Images->App Icons Source项右侧小箭头

在新开页面根据提示将对应尺寸的应用图标拖入到虚线框中即可

16 设置应用的splash图片

拷贝HBuider-Hello工程的info.plist文件的UILaunchImages节点到新工程info.plist文件,同时拷贝HBuilder-Hello工程下的splash目录到新工程目录下并将其添加到新工程中
根据图片的尺寸逐个替换splash图片,注意文件名不能修改

17 设置应用显示的应用名

点击project->target->General->Identity->Display Name修改应用的显示名称

18 修改info.plist文件,添加App Transport Security Settings类型为Dictionary,在该项下添加Allow Arbitrary Loads项类型为Boolean,值为YES

IOS 10 需要在info.plist文件中添加隐私权限配置

运行时如果提示“打包时未添加XXX模块”,(非中文提示时需要配置国际化),请参考SDK/Feature-ios.xls文件,查找对应插件名需要引入的5+库文件和系统库文件,添加到工程即可

Android创建最精简离线打包工程

收起阅读 »

HBuilder 原生APP插件开发

插件开发

辅助开发HBuilder的原生插件,有需求可联系QQ511308538 可定制开发插件

辅助开发HBuilder的原生插件,有需求可联系QQ511308538 可定制开发插件

为大家献上: H5+(持续更新 全面、深入的讲解 H5+)、MUI+(整套) 视频教程

mui

为大家献上: H5+(持续更新)、MUI+(整套) 视频教程。目前进度:

《H5+视频教程》更新中,月底前录制完毕共计20多节,全面讲解H5+的常用API。
视频观看地址
http://www.hcoder.net/course/info_212.html

《mui 教程》已经录制完毕并发布,视频观看地址:
http://www.hcoder.net/course/info_211.html

未来我们将推出项目教程,欢迎大家的意见建议!为了大家更好的学习我经常凌晨赶制,如果您觉得视频教程对您有所帮助,请帮忙顶贴(好东西不应该沉下去),谢谢了。

学习交流群: 335126794 入门密码: 超文本标记语言

继续阅读 »

为大家献上: H5+(持续更新)、MUI+(整套) 视频教程。目前进度:

《H5+视频教程》更新中,月底前录制完毕共计20多节,全面讲解H5+的常用API。
视频观看地址
http://www.hcoder.net/course/info_212.html

《mui 教程》已经录制完毕并发布,视频观看地址:
http://www.hcoder.net/course/info_211.html

未来我们将推出项目教程,欢迎大家的意见建议!为了大家更好的学习我经常凌晨赶制,如果您觉得视频教程对您有所帮助,请帮忙顶贴(好东西不应该沉下去),谢谢了。

学习交流群: 335126794 入门密码: 超文本标记语言

收起阅读 »

iframe的问题 大哥们给解答下啊

一个header 一个iframe iframe的第一个页面是一个列表 点击后进入详情页 如果列表过长往下滚动 下一个详情页 滚动条位置不对
安卓上没问题,ios上滚动条位置不对,第一个列表滚动到哪里 详情页就滚动到哪里,影响用户体验。

一个header 一个iframe iframe的第一个页面是一个列表 点击后进入详情页 如果列表过长往下滚动 下一个详情页 滚动条位置不对
安卓上没问题,ios上滚动条位置不对,第一个列表滚动到哪里 详情页就滚动到哪里,影响用户体验。

关于蓝牙设备搜索和Ble设备的搜索的简单调用方法

Native.JS 蓝牙

最近一段时间一直在调试蓝牙设备,论坛里面关于这方面资料的太少,特别是关于蓝牙4.0的案例,基本上没有,也只好摸石头过河了。目前的代码也就勉强能用,我希望在此抛砖引玉,大家一起来完善这一部分。

说明一下,蓝牙和蓝牙4.0调用的方法是不同的,我最开始没注意到这点,浪费了好多时间。

普通蓝牙搜索(安卓版)

var bArray = [];  
function scanBluetoothDevice(callback){  
    //获取android应用Activity对象  
    var main = plus.android.runtimeMainActivity();  
    //过滤器  
    var IntentFilter = plus.android.importClass('android.content.IntentFilter');  
    //蓝牙设备  
    var BluetoothDevice = plus.android.importClass("android.bluetooth.BluetoothDevice");  
    //蓝牙适配器  
    var BluetoothAdapter = plus.android.importClass("android.bluetooth.BluetoothAdapter");  

    var filter = new IntentFilter();  
    var BDevice = new BluetoothDevice();  
    //蓝牙本地适配器  
    var BAdapter = BluetoothAdapter.getDefaultAdapter();  

    // 判断是否开启蓝牙  
    if(!BAdapter.isEnabled()) {  
        BAdapter.enable(); //启动蓝牙  
    }  
    BAdapter.startDiscovery(); //开启搜索  

    var receiver = plus.android.implements('io.dcloud.android.content.BroadcastReceiver', {  
        onReceive: function(context, intent) { //回调  
            try {                 
                plus.android.importClass(intent); //通过intent实例引入intent类  
                if(intent.getAction() == "android.bluetooth.adapter.action.DISCOVERY_FINISHED") {  
                    main.unregisterReceiver(receiver); //取消监听     
                } else {  
                    //从Intent中获取设备对象  
                    BDevice= intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);  

                    if(BDevice == null) {  
                        main.unregisterReceiver(receiver); //取消监听  
                        return;  
                    }  

                    var name=BDevice.getAddress()+BDevice.getName();  
                    if(bArray.indexOf(name) == -1){     //去重  
                        bArray.push(name);  
                        callback({  
                            "name": BDevice.getName(),  
                            "SN": BDevice.getAddress()  
                        });   
                    }  

                }  
            } catch(e) {  
                console.error(e);  
            }  
        }  
    });  

    //main.unregisterReceiver(receiver); //取消监听,这一步可以不需要  

    filter.addAction(BDevice.ACTION_FOUND);  
    filter.addAction(BAdapter.ACTION_DISCOVERY_STARTED);  
    filter.addAction(BAdapter.ACTION_DISCOVERY_FINISHED);  
    filter.addAction(BAdapter.ACTION_STATE_CHANGED);  
    main.registerReceiver(receiver, filter); //注册监听   
}  

蓝牙4.0这部分,在安卓系统5.0及以上版本,需要使用新的api,之前的api无法使用,所以需要判断当前系统,分别使用不同的api来实现。IOS部分目前没有实现。

Ble设备搜索

function Ble() {  
    switch(plus.os.name) {  
        case "Android":  
            bleAndroid();  
            break;  
        case "iOS":  
            bleIOS();    //暂未实现  
            break;  
        default:  
            // 其它平台  
            plus.nativeUI.alert("暂不支持该系统");  
            break;  
    }  
}  

function bleAndroid(){  
    var main = plus.android.runtimeMainActivity();  
    var Intent = plus.android.importClass("android.content.Intent");  
    //蓝牙适配器  
    var BluetoothAdapter = plus.android.importClass("android.bluetooth.BluetoothAdapter");  
    var BAdapter = BluetoothAdapter.getDefaultAdapter();  

    var REQUEST_ENABLE_BT = 1;  
    // 判断是否开启蓝牙  
    if(!BAdapter.isEnabled()) {  
        var enableBtIntent = new Intent(BAdapter.ACTION_REQUEST_ENABLE);  
        main.startActivityForResult(enableBtIntent,REQUEST_ENABLE_BT);  
        return ;  
    }  

    //此判断当前android系统版本高于5.0  
    if(parseInt(plus.os.version) >= 5) {  
        bleAndroid5(BAdapter);    //Native.js无法反射抽象类,目前无法找到解决方法  
    } else {  
        bleAndroid4(BAdapter);  
    }  
}  

function bleAndroid4(BAdapter){  
    //蓝牙搜索回调  
    var mLeScanCallback = plus.android.implements("android.bluetooth.BluetoothAdapter$LeScanCallback", {  
        "onLeScan": function(device, rssi, scanRecord) {  
            // 可通过 scanRecord 获取Ble设备的uuid,major,minor  
        }  
    });  

    BAdapter.startLeScan(mLeScanCallback);  
    console.log("scan start!");  

    setTimeout(function() {  
        BAdapter.stopLeScan(mLeScanCallback);  
        console.log("scan end!");  
    },5000);  
}  

目前暂时就这些,后面在慢慢补充吧。

继续阅读 »

最近一段时间一直在调试蓝牙设备,论坛里面关于这方面资料的太少,特别是关于蓝牙4.0的案例,基本上没有,也只好摸石头过河了。目前的代码也就勉强能用,我希望在此抛砖引玉,大家一起来完善这一部分。

说明一下,蓝牙和蓝牙4.0调用的方法是不同的,我最开始没注意到这点,浪费了好多时间。

普通蓝牙搜索(安卓版)

var bArray = [];  
function scanBluetoothDevice(callback){  
    //获取android应用Activity对象  
    var main = plus.android.runtimeMainActivity();  
    //过滤器  
    var IntentFilter = plus.android.importClass('android.content.IntentFilter');  
    //蓝牙设备  
    var BluetoothDevice = plus.android.importClass("android.bluetooth.BluetoothDevice");  
    //蓝牙适配器  
    var BluetoothAdapter = plus.android.importClass("android.bluetooth.BluetoothAdapter");  

    var filter = new IntentFilter();  
    var BDevice = new BluetoothDevice();  
    //蓝牙本地适配器  
    var BAdapter = BluetoothAdapter.getDefaultAdapter();  

    // 判断是否开启蓝牙  
    if(!BAdapter.isEnabled()) {  
        BAdapter.enable(); //启动蓝牙  
    }  
    BAdapter.startDiscovery(); //开启搜索  

    var receiver = plus.android.implements('io.dcloud.android.content.BroadcastReceiver', {  
        onReceive: function(context, intent) { //回调  
            try {                 
                plus.android.importClass(intent); //通过intent实例引入intent类  
                if(intent.getAction() == "android.bluetooth.adapter.action.DISCOVERY_FINISHED") {  
                    main.unregisterReceiver(receiver); //取消监听     
                } else {  
                    //从Intent中获取设备对象  
                    BDevice= intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);  

                    if(BDevice == null) {  
                        main.unregisterReceiver(receiver); //取消监听  
                        return;  
                    }  

                    var name=BDevice.getAddress()+BDevice.getName();  
                    if(bArray.indexOf(name) == -1){     //去重  
                        bArray.push(name);  
                        callback({  
                            "name": BDevice.getName(),  
                            "SN": BDevice.getAddress()  
                        });   
                    }  

                }  
            } catch(e) {  
                console.error(e);  
            }  
        }  
    });  

    //main.unregisterReceiver(receiver); //取消监听,这一步可以不需要  

    filter.addAction(BDevice.ACTION_FOUND);  
    filter.addAction(BAdapter.ACTION_DISCOVERY_STARTED);  
    filter.addAction(BAdapter.ACTION_DISCOVERY_FINISHED);  
    filter.addAction(BAdapter.ACTION_STATE_CHANGED);  
    main.registerReceiver(receiver, filter); //注册监听   
}  

蓝牙4.0这部分,在安卓系统5.0及以上版本,需要使用新的api,之前的api无法使用,所以需要判断当前系统,分别使用不同的api来实现。IOS部分目前没有实现。

Ble设备搜索

function Ble() {  
    switch(plus.os.name) {  
        case "Android":  
            bleAndroid();  
            break;  
        case "iOS":  
            bleIOS();    //暂未实现  
            break;  
        default:  
            // 其它平台  
            plus.nativeUI.alert("暂不支持该系统");  
            break;  
    }  
}  

function bleAndroid(){  
    var main = plus.android.runtimeMainActivity();  
    var Intent = plus.android.importClass("android.content.Intent");  
    //蓝牙适配器  
    var BluetoothAdapter = plus.android.importClass("android.bluetooth.BluetoothAdapter");  
    var BAdapter = BluetoothAdapter.getDefaultAdapter();  

    var REQUEST_ENABLE_BT = 1;  
    // 判断是否开启蓝牙  
    if(!BAdapter.isEnabled()) {  
        var enableBtIntent = new Intent(BAdapter.ACTION_REQUEST_ENABLE);  
        main.startActivityForResult(enableBtIntent,REQUEST_ENABLE_BT);  
        return ;  
    }  

    //此判断当前android系统版本高于5.0  
    if(parseInt(plus.os.version) >= 5) {  
        bleAndroid5(BAdapter);    //Native.js无法反射抽象类,目前无法找到解决方法  
    } else {  
        bleAndroid4(BAdapter);  
    }  
}  

function bleAndroid4(BAdapter){  
    //蓝牙搜索回调  
    var mLeScanCallback = plus.android.implements("android.bluetooth.BluetoothAdapter$LeScanCallback", {  
        "onLeScan": function(device, rssi, scanRecord) {  
            // 可通过 scanRecord 获取Ble设备的uuid,major,minor  
        }  
    });  

    BAdapter.startLeScan(mLeScanCallback);  
    console.log("scan start!");  

    setTimeout(function() {  
        BAdapter.stopLeScan(mLeScanCallback);  
        console.log("scan end!");  
    },5000);  
}  

目前暂时就这些,后面在慢慢补充吧。

收起阅读 »

【公告】关于actionSheet 安卓样式错乱、iOS 10真机运行、提示PHP等问题的公告

文章地址:http://ask.dcloud.net.cn/article/900
HBuilder 7.5.0的android版本产生了actionSheet 样式错乱问题,该问题已经在最新的alpha版本修复。alpha版下载地址:http://pan.baidu.com/s/1hs0O4eS

HBuilder 7.5.0 已解决iOS10无法真机运行问题,Mac版暂未解决,大家可以使用xcode模拟器调试
更新后如无法使用请
①请在工具-插件安装中,安装iOS链接插件,如已安装请卸载后重新安装,重启HBuilder并重试
②检查是否安装有老版本的iTools,如有安装,请升级到最新版,未安装则无需处理

HBuilder7.4.2版出现的php文件无法使用大纲、无法使用alt+左键转到函数/变量定义等问题。
HBuilder 7.5.0已修复该问题,有此问题者请升级到此版本

如果想退回到历史版本,可以在官网下载界面下方点击历史版本链接。
注意HBuilder的历史版本里自带的真机运行基座都是严格的历史版本,但云端打包的引擎并不是严格和HBuilder历史版本对应的老版打包机,某些版本在云端打包机并不存在,此时会切换为使用最新版本打包。使用plus.runtime可以查看引擎版本。

继续阅读 »

文章地址:http://ask.dcloud.net.cn/article/900
HBuilder 7.5.0的android版本产生了actionSheet 样式错乱问题,该问题已经在最新的alpha版本修复。alpha版下载地址:http://pan.baidu.com/s/1hs0O4eS

HBuilder 7.5.0 已解决iOS10无法真机运行问题,Mac版暂未解决,大家可以使用xcode模拟器调试
更新后如无法使用请
①请在工具-插件安装中,安装iOS链接插件,如已安装请卸载后重新安装,重启HBuilder并重试
②检查是否安装有老版本的iTools,如有安装,请升级到最新版,未安装则无需处理

HBuilder7.4.2版出现的php文件无法使用大纲、无法使用alt+左键转到函数/变量定义等问题。
HBuilder 7.5.0已修复该问题,有此问题者请升级到此版本

如果想退回到历史版本,可以在官网下载界面下方点击历史版本链接。
注意HBuilder的历史版本里自带的真机运行基座都是严格的历史版本,但云端打包的引擎并不是严格和HBuilder历史版本对应的老版打包机,某些版本在云端打包机并不存在,此时会切换为使用最新版本打包。使用plus.runtime可以查看引擎版本。

收起阅读 »

EMMET

Emmet插件以前被称作为Zen Coding,是一个文本编辑器的插件,它可以帮助您快速编写HTML和CSS代码,从而加速Web前端开发。早在2009年,Sergey Chikuyonok写过一篇文章,提出编写HTML和CSS的新方法。这一革命性的插件指的就是Zen Coding,经过很多开发者多年来的努力与帮助,现在已达到了一个新的水平。也就是今天所说的Emme插件。
Emmet只是文本编辑器一个插件,要想让他发挥应用的功能,就得将其安装到你喜欢的文本编辑器中。到目前为止,很多流行的文本编辑器都支持Emmet插件,也就是说很多流行的文本编辑器都可以安装这款插件。
在Web前端开发中,我们不得不面对一个残酷的现实。在写HTML代码时需要一定的时间,因为我们要花大把的时间写HTML标签,属性,引号等;同样在编写CSS时,我们要写很多的属性、属性值,大括号和分号等。当然,大多数的文本编辑器都或多或少带有代码自动提示功能,在开发之时,帮了很大的忙,但仍然需要人工输入很多代码。而Emmet插件,集成了很多缩写,大家在开发时只需要输入简单的缩写,按tab键或ctrl+E键就能扩展出所需的代码片段。
假定你已经为您自己喜欢的文本编辑器成功的安装好了Emmet插件,接下来我们来简单的看看如何使用Emmet帮助您快速编写您的HTML标签。

Emmet使用定义的缩写来生成元素。他的语法和CSS的选择器非常类似:
一旦你写好缩写之后,按一下tab键(我使用的是Sublime Text编辑器)就能生成你所请求的代码。上面的例子将会产生下面的代码:
早前在《前端开发必备!Emmet使用手册》一文中详列了Emmet生成HTML代码的一些代码示例。接下来,让我们来深入一点了解Emmet语法,来看看如何通过一些更复杂的缩写创建HTML标签。

创建初始文档

任何一个HTML文件,都具有一些默认的文档结构。使用Emmet来创建需要的时间不到一秒。只要输入!或html:5,然后点击tab键,你就会看到一个HTML5的doctype默认标签。

html:5或!:HTML5文档类型
html:xt:XHTML过渡型文档类型
html:xs:XHTML严格型文档类型
html:4t:HTML4过渡型文档类型
html:4s:HTML4严格型文档类型
使用>运算符可以用来生成彼此嵌套的元素:
使用+运算符可以用来生成彼此相邻的元素:
使用^运算符,可以让你的代码返回上一层。当你使用>嵌套元素时,想让后面的回到上一层,那么这个方法很适用。
这个缩写将两个段落元素都放置在div内,但只有第一个段落里会包含一个链接。
乘法
如果你想一次性生成多个相同的元素,比如列表中的li,那么就可以使用乘法运算符
:
上面代码会生成5个li:
除了能一次性生成多个相同的标签之外,我们还可以通过$符号做递增;通过$@-符号做递减;通过$@3*5这样的方式从第三个开始命名:
组合

为了更有效的利用嵌套,我们常会制作一些代码片段。在Emmet中你可以通过()将一个块组合在一起,来看一个简单的示例:
上面的代码就会生成3个li,而且每个li中套了一个a:
在我们一个页面中,常会包括页头、主体和页脚三个部分,我们很多时候就可以通过对全们进行一个组合,快速生成有效的代码:
快速添加类名、ID、文本和属性

在Emmet中,还有一个功效,能快速帮助你添加类名、ID、文本和属性。

使用E#ID添加ID名
使用E.class添加类名
使用E[attr]添加属性
使用E{text}添加文本
省略标签名

在Emmet中可以省略标签名,默认情况下,如.item和div.item起到的作用是一致的<div class="item"></div>。在实际中还有几种情况:

ul和 ol中输入指的是li
table、tbody、thead和tfoot指的是tr
tr中指的是td
select和optgroup指的是option
Emmet和CSS

很多文章都是介绍Emmet和HTML之间的实现方式,但Josh Medeski的《Turbo-Charge Your CSS With Emmet》一文详细介绍了Emmet和CSS之间的实现方式。接下来的代码和图片主要来自于此文章。

属性

CSS提供了属性的值,比如font-size,margin和 padding等等:
Emmet定义了所有已知的CSS属性和缩写。所以border-bottom缩写是bdb,border-top缩写是bdt。正如下面的示例font-size缩写是fz:

假设你在你的编辑器中输入fz,然后按一下tab键,Emmet就像一个魔法师一样将缩写变成有效的CSS,并且放在你的光标之处。
属性值

现在我们已经了解了CSS的属性,它只需要添加一个值。这是通过一个组合缩写和所需要的值一起来完成。例如,fz18将输出font-size:18px。你不需要输入px,因为Emmet将会其单位是px。如果一个项目没有一个单位(如font-weight),Emmet会很聪明,他不会添加像素单位。
单位

如果你在CSS不经常使用的像素(px)单位,那会是什么?是em、rem、%、ex和px吗?那么这些单位在Emmet中都是可以使用的。在Emmet中每一个单位都有其缩写形式:

px→ 默认
p→ %
e→ em
r→ rem
x→ ex
要使用一个单位,只需要在值的后面使用缩写的单位值。下面的例子是使用em定义font-size:
多个单位

CSS中的某些属笥,比如margin,允许多个值。在Emmet中要做到这一点,只需要每个值之间使用破折号(-)。来看看下面的例子,给body定义margin的四个值:
颜色

在Emmet中使用#前缀,后面紧跟颜色值,但不同的字符数将会输出不同的十六进制代码。来看一些例子:

#1→ #111111
#E0→ #e0e0e0
#FC0→ #FFCC00
下面定义通过c#2定义body的颜色值,将会输出#222:
!important

尽管在CSS中!important并不经常使用,但在Emmet也带有一定的缩写。添加!就可以自动生成:
多属性

现在我们具Emmet的CSS特性的一个基本了解,也是将它们放在一起的时候。就类似于Emmet和HTML中的相邻元素的功能。可以使用加号+运算符来创建多个属性。我们来看一个简单的示例:
示例

记住,你可以使用所有缩写或者将其分开。这并不是很重要,关键的是你要使用得正确,它能更容易让你编写你的CSS。这里有一个动画,他给div.panel创建一些样式:
总结

Emmet是一个强大的工具,也被称为是一款高速的编码工具,它可以让你花更少的时间做同样的事情,而无需手动创建自己的代码片段。Emmet的灵感来自于CSS选择器以及可以用于所有主要的文本编辑器,以适应开发者的工作流程。

请记住,你可以在你的工作流中添加任何新工具,这个学习过程也是一个曲线的过程,但你不要花费更多的时间做那些相同的事情。你只是需要定期的访问 Emmet文档,你就会慢慢熟悉Emmet中HTML和CSS的所有特性。让你少想,少写,实现更多想要的代码。
文章来源:http://www.w3cplus.com/tools/using-emmet-speed-front-end-web-development.html

继续阅读 »

Emmet插件以前被称作为Zen Coding,是一个文本编辑器的插件,它可以帮助您快速编写HTML和CSS代码,从而加速Web前端开发。早在2009年,Sergey Chikuyonok写过一篇文章,提出编写HTML和CSS的新方法。这一革命性的插件指的就是Zen Coding,经过很多开发者多年来的努力与帮助,现在已达到了一个新的水平。也就是今天所说的Emme插件。
Emmet只是文本编辑器一个插件,要想让他发挥应用的功能,就得将其安装到你喜欢的文本编辑器中。到目前为止,很多流行的文本编辑器都支持Emmet插件,也就是说很多流行的文本编辑器都可以安装这款插件。
在Web前端开发中,我们不得不面对一个残酷的现实。在写HTML代码时需要一定的时间,因为我们要花大把的时间写HTML标签,属性,引号等;同样在编写CSS时,我们要写很多的属性、属性值,大括号和分号等。当然,大多数的文本编辑器都或多或少带有代码自动提示功能,在开发之时,帮了很大的忙,但仍然需要人工输入很多代码。而Emmet插件,集成了很多缩写,大家在开发时只需要输入简单的缩写,按tab键或ctrl+E键就能扩展出所需的代码片段。
假定你已经为您自己喜欢的文本编辑器成功的安装好了Emmet插件,接下来我们来简单的看看如何使用Emmet帮助您快速编写您的HTML标签。

Emmet使用定义的缩写来生成元素。他的语法和CSS的选择器非常类似:
一旦你写好缩写之后,按一下tab键(我使用的是Sublime Text编辑器)就能生成你所请求的代码。上面的例子将会产生下面的代码:
早前在《前端开发必备!Emmet使用手册》一文中详列了Emmet生成HTML代码的一些代码示例。接下来,让我们来深入一点了解Emmet语法,来看看如何通过一些更复杂的缩写创建HTML标签。

创建初始文档

任何一个HTML文件,都具有一些默认的文档结构。使用Emmet来创建需要的时间不到一秒。只要输入!或html:5,然后点击tab键,你就会看到一个HTML5的doctype默认标签。

html:5或!:HTML5文档类型
html:xt:XHTML过渡型文档类型
html:xs:XHTML严格型文档类型
html:4t:HTML4过渡型文档类型
html:4s:HTML4严格型文档类型
使用>运算符可以用来生成彼此嵌套的元素:
使用+运算符可以用来生成彼此相邻的元素:
使用^运算符,可以让你的代码返回上一层。当你使用>嵌套元素时,想让后面的回到上一层,那么这个方法很适用。
这个缩写将两个段落元素都放置在div内,但只有第一个段落里会包含一个链接。
乘法
如果你想一次性生成多个相同的元素,比如列表中的li,那么就可以使用乘法运算符
:
上面代码会生成5个li:
除了能一次性生成多个相同的标签之外,我们还可以通过$符号做递增;通过$@-符号做递减;通过$@3*5这样的方式从第三个开始命名:
组合

为了更有效的利用嵌套,我们常会制作一些代码片段。在Emmet中你可以通过()将一个块组合在一起,来看一个简单的示例:
上面的代码就会生成3个li,而且每个li中套了一个a:
在我们一个页面中,常会包括页头、主体和页脚三个部分,我们很多时候就可以通过对全们进行一个组合,快速生成有效的代码:
快速添加类名、ID、文本和属性

在Emmet中,还有一个功效,能快速帮助你添加类名、ID、文本和属性。

使用E#ID添加ID名
使用E.class添加类名
使用E[attr]添加属性
使用E{text}添加文本
省略标签名

在Emmet中可以省略标签名,默认情况下,如.item和div.item起到的作用是一致的<div class="item"></div>。在实际中还有几种情况:

ul和 ol中输入指的是li
table、tbody、thead和tfoot指的是tr
tr中指的是td
select和optgroup指的是option
Emmet和CSS

很多文章都是介绍Emmet和HTML之间的实现方式,但Josh Medeski的《Turbo-Charge Your CSS With Emmet》一文详细介绍了Emmet和CSS之间的实现方式。接下来的代码和图片主要来自于此文章。

属性

CSS提供了属性的值,比如font-size,margin和 padding等等:
Emmet定义了所有已知的CSS属性和缩写。所以border-bottom缩写是bdb,border-top缩写是bdt。正如下面的示例font-size缩写是fz:

假设你在你的编辑器中输入fz,然后按一下tab键,Emmet就像一个魔法师一样将缩写变成有效的CSS,并且放在你的光标之处。
属性值

现在我们已经了解了CSS的属性,它只需要添加一个值。这是通过一个组合缩写和所需要的值一起来完成。例如,fz18将输出font-size:18px。你不需要输入px,因为Emmet将会其单位是px。如果一个项目没有一个单位(如font-weight),Emmet会很聪明,他不会添加像素单位。
单位

如果你在CSS不经常使用的像素(px)单位,那会是什么?是em、rem、%、ex和px吗?那么这些单位在Emmet中都是可以使用的。在Emmet中每一个单位都有其缩写形式:

px→ 默认
p→ %
e→ em
r→ rem
x→ ex
要使用一个单位,只需要在值的后面使用缩写的单位值。下面的例子是使用em定义font-size:
多个单位

CSS中的某些属笥,比如margin,允许多个值。在Emmet中要做到这一点,只需要每个值之间使用破折号(-)。来看看下面的例子,给body定义margin的四个值:
颜色

在Emmet中使用#前缀,后面紧跟颜色值,但不同的字符数将会输出不同的十六进制代码。来看一些例子:

#1→ #111111
#E0→ #e0e0e0
#FC0→ #FFCC00
下面定义通过c#2定义body的颜色值,将会输出#222:
!important

尽管在CSS中!important并不经常使用,但在Emmet也带有一定的缩写。添加!就可以自动生成:
多属性

现在我们具Emmet的CSS特性的一个基本了解,也是将它们放在一起的时候。就类似于Emmet和HTML中的相邻元素的功能。可以使用加号+运算符来创建多个属性。我们来看一个简单的示例:
示例

记住,你可以使用所有缩写或者将其分开。这并不是很重要,关键的是你要使用得正确,它能更容易让你编写你的CSS。这里有一个动画,他给div.panel创建一些样式:
总结

Emmet是一个强大的工具,也被称为是一款高速的编码工具,它可以让你花更少的时间做同样的事情,而无需手动创建自己的代码片段。Emmet的灵感来自于CSS选择器以及可以用于所有主要的文本编辑器,以适应开发者的工作流程。

请记住,你可以在你的工作流中添加任何新工具,这个学习过程也是一个曲线的过程,但你不要花费更多的时间做那些相同的事情。你只是需要定期的访问 Emmet文档,你就会慢慢熟悉Emmet中HTML和CSS的所有特性。让你少想,少写,实现更多想要的代码。
文章来源:http://www.w3cplus.com/tools/using-emmet-speed-front-end-web-development.html

收起阅读 »

安卓打包后,微信登录提示“认证失败,原因:用户取消”

微信登录

解决方案如下:

1、微信登录打包后才能测试
2、如果使用的是微信开放平台的移动应用,那么打包app时使用的包名和移动应用设置的包名是否一致
3、微信开放平台移动应用中设置的应用签名是否是根据上述包名生成的
4、微信注销再登录一切就正常。

签名生成工具: 用于获取安装到手机的第三方应用签名的apk包
https://res.wx.qq.com/open/zh_CN/htmledition/res/dev/download/sdk/Gen_Signature_Android221cbf.apk

继续阅读 »

解决方案如下:

1、微信登录打包后才能测试
2、如果使用的是微信开放平台的移动应用,那么打包app时使用的包名和移动应用设置的包名是否一致
3、微信开放平台移动应用中设置的应用签名是否是根据上述包名生成的
4、微信注销再登录一切就正常。

签名生成工具: 用于获取安装到手机的第三方应用签名的apk包
https://res.wx.qq.com/open/zh_CN/htmledition/res/dev/download/sdk/Gen_Signature_Android221cbf.apk

收起阅读 »

[mui]自定义样式与mui冲突不生效的解决方式

mui

使用important强制提升优先级

.test {  
    height: 23px!important;  
    line-height: 23px!important;  
}

使用important强制提升优先级

.test {  
    height: 23px!important;  
    line-height: 23px!important;  
}

大白话解释如何使用DCloud的图片延迟加载(懒加载、lazyload)

懒加载

像我这样的“百度流”、“社区流”小白,从乱翻资料到成功使用DC的每一个功能,都是一个痛苦的过程。
事实上,DC提供了优秀且易用的lazyload机制。不仅可以在app使用,也可以在web开发过程中使用。其还具有一个特别的优点:在tab滑动页面状态为隐藏时,自动启用lazyload机制,切换为显示时才载入真实图片,大大节省流量。

经试验,只要满足以下几点,就能跑起来:

约定:{$tplRoot}表示模板所在路径,应按照实际情况修改。chrome 下用F12键进入调试,不报404为准。

一、在所需页面,成功引入以下三个js。

<script type="text/javascript" src="{$tplRoot}/mui/js/mui.min.js"></script>  
<script type="text/javascript" src="{$tplRoot}/mui/js/mui.lazyload.js"></script>  
<script type="text/javascript" src="{$tplRoot}/mui/js/mui.lazyload.img.js"></script>

为保证ui效果,建议引入以下CSS

<link rel="stylesheet" href="{$tplRoot}/mui/css/mui.min.css">

二、html结构
不论是用js动态生成,还是用其他方法生成html,都要按照以下规范:

<div id="img-content-app">  
  <div class="rich_media_content">  
    <!--其他html-->  
    <img data-lazyload="图片实际地址" src="临时占位图片地址">  
    <!--其他html-->  
  </div>  
</div>

注:测试时内容至少搞成三四屏以上,一屏当然启动不了lazyload。

三、在body区域加入以下JS代码

<script type="text/javascript" charset="utf-8">  
    var list = document.getElementById("img-content-app");//表示需要实施lazyload的div区域,指定其id。  
    var lazyLoadApi = mui('#img-content-app .rich_media_content').imageLazyload({//.rich_media_content指定lazyload实施区域的div class  
        autoDestroy: false,  
        placeholder: '{$tplRoot}/images/60x60.gif'//在js里指定临时占位图片,需自行准备并指定正确的本地路径或远程路径  
    });  
    mui.init();  

// ...other script...  

</script>

解释:
一、可以看到,html里的div之id、class与js里应该写成一致。具体写成什么,并不重要。但###必须要对应###。
二、需要lazy区域里的图片一定要有data-lazyload。

示例:https://app.lijiangtv.com/index.php?s=/addon/AppManage/Client/index/aid/1660

继续阅读 »

像我这样的“百度流”、“社区流”小白,从乱翻资料到成功使用DC的每一个功能,都是一个痛苦的过程。
事实上,DC提供了优秀且易用的lazyload机制。不仅可以在app使用,也可以在web开发过程中使用。其还具有一个特别的优点:在tab滑动页面状态为隐藏时,自动启用lazyload机制,切换为显示时才载入真实图片,大大节省流量。

经试验,只要满足以下几点,就能跑起来:

约定:{$tplRoot}表示模板所在路径,应按照实际情况修改。chrome 下用F12键进入调试,不报404为准。

一、在所需页面,成功引入以下三个js。

<script type="text/javascript" src="{$tplRoot}/mui/js/mui.min.js"></script>  
<script type="text/javascript" src="{$tplRoot}/mui/js/mui.lazyload.js"></script>  
<script type="text/javascript" src="{$tplRoot}/mui/js/mui.lazyload.img.js"></script>

为保证ui效果,建议引入以下CSS

<link rel="stylesheet" href="{$tplRoot}/mui/css/mui.min.css">

二、html结构
不论是用js动态生成,还是用其他方法生成html,都要按照以下规范:

<div id="img-content-app">  
  <div class="rich_media_content">  
    <!--其他html-->  
    <img data-lazyload="图片实际地址" src="临时占位图片地址">  
    <!--其他html-->  
  </div>  
</div>

注:测试时内容至少搞成三四屏以上,一屏当然启动不了lazyload。

三、在body区域加入以下JS代码

<script type="text/javascript" charset="utf-8">  
    var list = document.getElementById("img-content-app");//表示需要实施lazyload的div区域,指定其id。  
    var lazyLoadApi = mui('#img-content-app .rich_media_content').imageLazyload({//.rich_media_content指定lazyload实施区域的div class  
        autoDestroy: false,  
        placeholder: '{$tplRoot}/images/60x60.gif'//在js里指定临时占位图片,需自行准备并指定正确的本地路径或远程路径  
    });  
    mui.init();  

// ...other script...  

</script>

解释:
一、可以看到,html里的div之id、class与js里应该写成一致。具体写成什么,并不重要。但###必须要对应###。
二、需要lazy区域里的图片一定要有data-lazyload。

示例:https://app.lijiangtv.com/index.php?s=/addon/AppManage/Client/index/aid/1660

收起阅读 »

IOS 10 需要在info.plist文件中添加隐私权限配置

SDK iOS

iOS 10 开始对隐私权限更加严格, 如需使用隐私权限需要在工程的info.plist文件中声明,如果不声明程序在调用隐私权限(如相机)时应用程序会崩溃
离线打包用户需要手动添加权限到打包工程的info.plist文件中

key可从以下表中获取,value为弹框提示文字用户可随意添加,类型String

权限名称 Key值
通讯录 NSContactsUsageDescription
麦克风 NSMicrophoneUsageDescription
相册 NSPhotoLibraryUsageDescription
相机 NSCameraUsageDescription
添加图片到相册 NSPhotoLibraryAddUsageDescription
持续获取地理位置 NSLocationAlwaysUsageDescription
使用时获取地理位置 NSLocationWhenInUseUsageDescription
蓝牙 NSBluetoothPeripheralUsageDescription
语音转文字 NSSpeechRecognitionUsageDescription
日历 NSCalendarsUsageDescription

苹果最新的审核规范要求申请隐私权限弹框必须要详细说明获取该权限的目的,配置时请详细说明应用中使用该权限的目的
云打包设置提示语方法请参考链接http://ask.dcloud.net.cn/article/12964

继续阅读 »

iOS 10 开始对隐私权限更加严格, 如需使用隐私权限需要在工程的info.plist文件中声明,如果不声明程序在调用隐私权限(如相机)时应用程序会崩溃
离线打包用户需要手动添加权限到打包工程的info.plist文件中

key可从以下表中获取,value为弹框提示文字用户可随意添加,类型String

权限名称 Key值
通讯录 NSContactsUsageDescription
麦克风 NSMicrophoneUsageDescription
相册 NSPhotoLibraryUsageDescription
相机 NSCameraUsageDescription
添加图片到相册 NSPhotoLibraryAddUsageDescription
持续获取地理位置 NSLocationAlwaysUsageDescription
使用时获取地理位置 NSLocationWhenInUseUsageDescription
蓝牙 NSBluetoothPeripheralUsageDescription
语音转文字 NSSpeechRecognitionUsageDescription
日历 NSCalendarsUsageDescription

苹果最新的审核规范要求申请隐私权限弹框必须要详细说明获取该权限的目的,配置时请详细说明应用中使用该权限的目的
云打包设置提示语方法请参考链接http://ask.dcloud.net.cn/article/12964

收起阅读 »

开发Hbuilder 原生iOS插件,目前已开发蓝牙打印机,扫码功能插件

插件开发

开发Hbuilder 原生iOS插件,目前已开发蓝牙打印机,扫码功能插件
注意 是原生iOS插件,提供调用方法,返回结果
iOS原生的代码,插件,跟hbuilder官方插件一样的使用方式

QQ511308538

开发Hbuilder 原生iOS插件,目前已开发蓝牙打印机,扫码功能插件
注意 是原生iOS插件,提供调用方法,返回结果
iOS原生的代码,插件,跟hbuilder官方插件一样的使用方式

QQ511308538