
开始使用 HBuilder 和 Mui - 1 - 分析 index.html ;
好吧,在比较了 Codenameone 和 HBuilder 以后,俺反复考虑后,终于还是决定使用 HBuilder 这个东东;
简单说说 Codenameone 吧,用 java 进行开发的跨平台(注意,目前支持 android, ios, wp, BlackBerry) 的框架,首先吸引我的是它的跨平台移动开发能力, 其次吧,编译型的语言比较好进行TDD开发, 第三,有一个可视化的界面设计环境以及界面设计和处理代码相分离的处理逻辑,第四,无需虚拟机直接可以在本地的JAVA IDE中运行进行测试和调试;
但是,讨厌的几个问题是,1.需要翻墙, 2.文档全E文, 3. 除了API之外,基本没有文档;
好吧,闲话少说,开始使用 HBuilder;
俺就不吐槽文档MUI文档缺少的问题了;(建议首先一定要仔细看 mui 的那个文档至少3遍,对于里面的所有变量定义有一个大致印象,否则,对于比较喜欢寻根究底的人(比如说我)来说,会比较辛苦);
先创建一个 HelloMUI 的例子项目;在手机上运行,很好;在AVD的模拟器上运行,也很好;
用 chrome 浏览器连接真机想Inspect进行调试,已经看到打开哪些网页l了,但就是Inspect不了,好吧,我的手机是红米,目前是4.2,需要4.4.2才支持;
用 chrome 浏览器连接AVD的虚拟机来Inspect进行调试,同样看到打开哪些网页l了,但就是Inspect不了,好吧,翻墙,给 chrome安装上ADB插件,还是 Inspect不了;
好吧,安装上了一个号称快得多的Genymotion,再下了一个4.4.4的镜像,终于可以用chrome注入进行代码调试了;
但是,谁说额Genymotion速度要快的啊?除了虚拟机启动速度快那么一点意外,
俺的I7、8G内存跑HelloMui无论是启动速度还是响应速度,比起安装上 InterHAXL 再加 Inter ATOM 的虚拟机速度慢的实在太多了;
好吧,俺忍。。。。等 魅蓝Note2 出来俺就换手机;
开始仔细看 index.html 的代码和 List.html 的代码;
好吧,目前为止 , 可以知道 mui.init 里面那个object带的属性有:
swipeBack:true //启用右滑关闭功能
statusBarBackground: '#f7f7f7',
gestureConfig:{
doubletap:true
},
subpages: [{
id: 'list',
url: 'list.html',
styles: {
top: '45px',
bottom: 0,
bounce: 'vertical'
}
},
styles:{ .... }
那么 statusBarBackground 这个参数是干啥的呢?貌似是状态栏的背景颜色,有没有其他类似的其他属性呢?不知道;
甚至, statusBarBackground 这个属性在 MUI自己的API文档里提都没有提到过,是我在 index.html的第27行里面翻出来的;
好吧,继续往下看, mui.os 这个又什么东东?继续翻API,很遗憾,还是没有;
看 HBuilder的提示, mui里面有 ajaxSetting, data, fn, os, gestures, options 。等几个属性,好吧,大家暂时记得 mui.os 里面记录了操作系统的一些环境变量的定义就可以了;至于其他属性,大家就当没有看到吧;
那个弹出菜单因为俺估计用不到,所以嘛,就跳过了;
继续往下看,到了显示关于 页面的处理了;
俺贴出代码吧,
document.getElementById('info').addEventListener('tap', function() {
if (subWebview == null) {
//获取共用父窗体
template = plus.webview.getWebviewById("default-main");
}
if(template){
subWebview = template.children()[0];
subWebview.loadURL('examples/info.html');
//修改共用父模板的标题
mui.fire(template, 'updateHeader', {
title: '关于XXXX',
showMenu: false
});
template.show('slide-in-right', 150);
}
});
plus.webview.getWebviewById("default-main"); 这个 default-main 是啥东东??
开 MUI API文档,没有; 看 H5 Api文档,还是没有;整个项目查找, 稀奇了,还是没有:
好吧,俺承认失败了,姑且认为 default-main 是整个程序第一个加载的页面吧;(这个看法是错误的,稍后会说明);
继续往下看,没有其他需要注意的地方了;真的没有了?
template.children()[0] 这个是啥东东,问题回到原点,归根结底还是需要知道 plus.webview.getWebviewById("default-main") 是什么东东;
暂时放下这个问题, subWebview.loadURL('examples/info.html'); 这个没有疑问;
//修改共用父模板的标题
mui.fire(template, 'updateHeader', {
title: '关于XXXX',
showMenu: false
});
template.show('slide-in-right', 150);
很简单吧?没有这么简单;大家打开 examples/info.html 这个页面,会发现里面也定义了 Header,俺比较偏执,总觉得这儿不应该定义 Header,于是就把 info.html 页面里面的 Header 给注释掉了,呵呵,果然标题照样给改掉了;
说明什么?说明, mui.fire(template, 'updateHeader' 这个修改的不是 info.html 里面 Header 定义的标题;
好吧,打开 关于 页面,再按 Back 按钮,首页标题还是 Hello mui,
说明什么?说明,mui.fire(template, 'updateHeader' 这个修改的不是 index.html 里面 Header 定义的标题;
那么到底修改的是哪儿的Header的内容?
再次打开 关于 页面,可以发现 页面切换时会显示 加载中 这三个字;本来我以为这个是 mui 在页面切换时的自动提示,但还是在整个项目中搜了一下,居然发现在 example/template.html 中有这个三个字,怀着好奇的心情,俺把这三个字改成了 TMD , 结果,呵呵,页面切换时果然显示了 TMD ;
好吧,俺服了;继续找 template.html 在哪儿被引用;
list.html 中有这样的定义: getTemplate('default', 'examples/template.html'); 再看 getTemplate的方法定义,
var headerWebview = mui.preload({
url:header,
id:name "-main",
styles:{
popGesture:"hide",
},
extras:{
mType: 'main'
}
});
终于,俺们找到了 default-main 是在哪儿定义的了;
再看下面的代码,headerWebview.append(subWebview); 终于也找到 template.children()[0] 是啥东东了。。。
说到这儿,大家以为完了?哪有这么简单;
subWebview.loadURL('examples/info.html'); 大家还记得吧,上面我把 info.html 的 Header部分注释掉了,现在俺把 Header 给改回来,
那么 这个 subWebview 加载的页面应该也包含有 一个 Header, 可是这个 info.html 里面的这个 Header 无论如何也不会显示出来?
现在,问题来了,这个 Header 到底到哪儿去了?
暂时就这样了;
经过这个这个分析,俺有些怀疑自己的选择了。。。
好吧,在比较了 Codenameone 和 HBuilder 以后,俺反复考虑后,终于还是决定使用 HBuilder 这个东东;
简单说说 Codenameone 吧,用 java 进行开发的跨平台(注意,目前支持 android, ios, wp, BlackBerry) 的框架,首先吸引我的是它的跨平台移动开发能力, 其次吧,编译型的语言比较好进行TDD开发, 第三,有一个可视化的界面设计环境以及界面设计和处理代码相分离的处理逻辑,第四,无需虚拟机直接可以在本地的JAVA IDE中运行进行测试和调试;
但是,讨厌的几个问题是,1.需要翻墙, 2.文档全E文, 3. 除了API之外,基本没有文档;
好吧,闲话少说,开始使用 HBuilder;
俺就不吐槽文档MUI文档缺少的问题了;(建议首先一定要仔细看 mui 的那个文档至少3遍,对于里面的所有变量定义有一个大致印象,否则,对于比较喜欢寻根究底的人(比如说我)来说,会比较辛苦);
先创建一个 HelloMUI 的例子项目;在手机上运行,很好;在AVD的模拟器上运行,也很好;
用 chrome 浏览器连接真机想Inspect进行调试,已经看到打开哪些网页l了,但就是Inspect不了,好吧,我的手机是红米,目前是4.2,需要4.4.2才支持;
用 chrome 浏览器连接AVD的虚拟机来Inspect进行调试,同样看到打开哪些网页l了,但就是Inspect不了,好吧,翻墙,给 chrome安装上ADB插件,还是 Inspect不了;
好吧,安装上了一个号称快得多的Genymotion,再下了一个4.4.4的镜像,终于可以用chrome注入进行代码调试了;
但是,谁说额Genymotion速度要快的啊?除了虚拟机启动速度快那么一点意外,
俺的I7、8G内存跑HelloMui无论是启动速度还是响应速度,比起安装上 InterHAXL 再加 Inter ATOM 的虚拟机速度慢的实在太多了;
好吧,俺忍。。。。等 魅蓝Note2 出来俺就换手机;
开始仔细看 index.html 的代码和 List.html 的代码;
好吧,目前为止 , 可以知道 mui.init 里面那个object带的属性有:
swipeBack:true //启用右滑关闭功能
statusBarBackground: '#f7f7f7',
gestureConfig:{
doubletap:true
},
subpages: [{
id: 'list',
url: 'list.html',
styles: {
top: '45px',
bottom: 0,
bounce: 'vertical'
}
},
styles:{ .... }
那么 statusBarBackground 这个参数是干啥的呢?貌似是状态栏的背景颜色,有没有其他类似的其他属性呢?不知道;
甚至, statusBarBackground 这个属性在 MUI自己的API文档里提都没有提到过,是我在 index.html的第27行里面翻出来的;
好吧,继续往下看, mui.os 这个又什么东东?继续翻API,很遗憾,还是没有;
看 HBuilder的提示, mui里面有 ajaxSetting, data, fn, os, gestures, options 。等几个属性,好吧,大家暂时记得 mui.os 里面记录了操作系统的一些环境变量的定义就可以了;至于其他属性,大家就当没有看到吧;
那个弹出菜单因为俺估计用不到,所以嘛,就跳过了;
继续往下看,到了显示关于 页面的处理了;
俺贴出代码吧,
document.getElementById('info').addEventListener('tap', function() {
if (subWebview == null) {
//获取共用父窗体
template = plus.webview.getWebviewById("default-main");
}
if(template){
subWebview = template.children()[0];
subWebview.loadURL('examples/info.html');
//修改共用父模板的标题
mui.fire(template, 'updateHeader', {
title: '关于XXXX',
showMenu: false
});
template.show('slide-in-right', 150);
}
});
plus.webview.getWebviewById("default-main"); 这个 default-main 是啥东东??
开 MUI API文档,没有; 看 H5 Api文档,还是没有;整个项目查找, 稀奇了,还是没有:
好吧,俺承认失败了,姑且认为 default-main 是整个程序第一个加载的页面吧;(这个看法是错误的,稍后会说明);
继续往下看,没有其他需要注意的地方了;真的没有了?
template.children()[0] 这个是啥东东,问题回到原点,归根结底还是需要知道 plus.webview.getWebviewById("default-main") 是什么东东;
暂时放下这个问题, subWebview.loadURL('examples/info.html'); 这个没有疑问;
//修改共用父模板的标题
mui.fire(template, 'updateHeader', {
title: '关于XXXX',
showMenu: false
});
template.show('slide-in-right', 150);
很简单吧?没有这么简单;大家打开 examples/info.html 这个页面,会发现里面也定义了 Header,俺比较偏执,总觉得这儿不应该定义 Header,于是就把 info.html 页面里面的 Header 给注释掉了,呵呵,果然标题照样给改掉了;
说明什么?说明, mui.fire(template, 'updateHeader' 这个修改的不是 info.html 里面 Header 定义的标题;
好吧,打开 关于 页面,再按 Back 按钮,首页标题还是 Hello mui,
说明什么?说明,mui.fire(template, 'updateHeader' 这个修改的不是 index.html 里面 Header 定义的标题;
那么到底修改的是哪儿的Header的内容?
再次打开 关于 页面,可以发现 页面切换时会显示 加载中 这三个字;本来我以为这个是 mui 在页面切换时的自动提示,但还是在整个项目中搜了一下,居然发现在 example/template.html 中有这个三个字,怀着好奇的心情,俺把这三个字改成了 TMD , 结果,呵呵,页面切换时果然显示了 TMD ;
好吧,俺服了;继续找 template.html 在哪儿被引用;
list.html 中有这样的定义: getTemplate('default', 'examples/template.html'); 再看 getTemplate的方法定义,
var headerWebview = mui.preload({
url:header,
id:name "-main",
styles:{
popGesture:"hide",
},
extras:{
mType: 'main'
}
});
终于,俺们找到了 default-main 是在哪儿定义的了;
再看下面的代码,headerWebview.append(subWebview); 终于也找到 template.children()[0] 是啥东东了。。。
说到这儿,大家以为完了?哪有这么简单;
subWebview.loadURL('examples/info.html'); 大家还记得吧,上面我把 info.html 的 Header部分注释掉了,现在俺把 Header 给改回来,
那么 这个 subWebview 加载的页面应该也包含有 一个 Header, 可是这个 info.html 里面的这个 Header 无论如何也不会显示出来?
现在,问题来了,这个 Header 到底到哪儿去了?
暂时就这样了;
经过这个这个分析,俺有些怀疑自己的选择了。。。
收起阅读 »
Appstore提交错误及解决方案
问题1:

解决方案:
进入Apple MemberCenter,去掉appid的Associated Domains,重新生成profile文件重新打包
问题2:
上传app,一直卡在“正在通过 App Store 进行鉴定”
http://ask.dcloud.net.cn/question/6792
问题3:
ERROR ITMS-90085: "No architectures in the binary. Lipo failed to detect any architectures in the bundle executable."
生成的api分析文件太大,我们无法在交付前验证您的api信息
http://ask.dcloud.net.cn/question/10148
问题4
解决方案:
这个是缺少启动图片导致的,请保证配置了启动图和启动图格式正确
问题5
QQ分享 IOS 审核被拒的问题
http://ask.dcloud.net.cn/question/10368
问题6
This bundle is invalid - The Info.plist file for /Payload/DCloud_Pandora.app/Pandora/apps/com.taitaikg.app is missing or could not be read.
Invalid Bundle - The bundle at '/Payload/DCloud_Pandora.app/Pandora/apps/com.taitaikg.app' does not contain a bundle executable.
http://ask.dcloud.net.cn/question/15088
问题7
上传提示
you must define an input diretory
http://ask.dcloud.net.cn/question/5504
问题1:
解决方案:
进入Apple MemberCenter,去掉appid的Associated Domains,重新生成profile文件重新打包
问题2:
上传app,一直卡在“正在通过 App Store 进行鉴定”
http://ask.dcloud.net.cn/question/6792
问题3:
ERROR ITMS-90085: "No architectures in the binary. Lipo failed to detect any architectures in the bundle executable."
生成的api分析文件太大,我们无法在交付前验证您的api信息
http://ask.dcloud.net.cn/question/10148
问题4
解决方案:
这个是缺少启动图片导致的,请保证配置了启动图和启动图格式正确
问题5
QQ分享 IOS 审核被拒的问题
http://ask.dcloud.net.cn/question/10368
问题6
This bundle is invalid - The Info.plist file for /Payload/DCloud_Pandora.app/Pandora/apps/com.taitaikg.app is missing or could not be read.
Invalid Bundle - The bundle at '/Payload/DCloud_Pandora.app/Pandora/apps/com.taitaikg.app' does not contain a bundle executable.
http://ask.dcloud.net.cn/question/15088
问题7
上传提示
you must define an input diretory
http://ask.dcloud.net.cn/question/5504

Android配置应用主题皮肤
5+ API中提供plus.nativeUI.*提供系统原生类控件的调用,其样式由Android平台提供界面主题决定,新版本(5.9.0)App云端打包默认为“@android:style/Theme.DeviceDefault.Light”(以前版本默认为“@android:style/Theme.DeviceDefault”)。
从5.9.0版本后HBuilder可支持自定义程序主题,打开应用的manifest.json文件,切换到“代码视图”
- 5+ APP
在 "plus" -> "distribute" -> "google" 节点下添加“theme”字段 - uni-app
在 "app-plus" -> "distribute" -> "android" 节点下添加“theme”字段
并配置要使用的应用主题:
值为字符串类型,必须是Android系统支持的类型,注意云端打包编译环境。
- HBuilder
Android4.4(API Level19)SDK - HBuilderX
Android Q (API Level29)SDK
如果输入的类型无效则会提示以下错误:
res/values/dcloud_activity_styles.xml:2: error: Error retrieving parent for item: No resource found that matches the given name 'XXXXXXXXXXXXXXXX'.
推荐使用以下主题样式
- @android:style/Theme.DeviceDefault
系统默认样式(暗色系),通常是黑底白字 - @android:style/Theme.DeviceDefault.Light
系统默认明亮样式(亮色系),通常是白底黑字
Android API19支持的样式列表如下:
配置完成保存提交App云端打包后才能生效
注意!!!更改主题时建议使用NoActionBar系列主题。如果配置其他样式主题可能会导致页面顶部多出一个ActionBar UI(actionBar)
5+ API中提供plus.nativeUI.*提供系统原生类控件的调用,其样式由Android平台提供界面主题决定,新版本(5.9.0)App云端打包默认为“@android:style/Theme.DeviceDefault.Light”(以前版本默认为“@android:style/Theme.DeviceDefault”)。
从5.9.0版本后HBuilder可支持自定义程序主题,打开应用的manifest.json文件,切换到“代码视图”
- 5+ APP
在 "plus" -> "distribute" -> "google" 节点下添加“theme”字段 - uni-app
在 "app-plus" -> "distribute" -> "android" 节点下添加“theme”字段
并配置要使用的应用主题:
值为字符串类型,必须是Android系统支持的类型,注意云端打包编译环境。
- HBuilder
Android4.4(API Level19)SDK - HBuilderX
Android Q (API Level29)SDK
如果输入的类型无效则会提示以下错误:
res/values/dcloud_activity_styles.xml:2: error: Error retrieving parent for item: No resource found that matches the given name 'XXXXXXXXXXXXXXXX'.
推荐使用以下主题样式
- @android:style/Theme.DeviceDefault
系统默认样式(暗色系),通常是黑底白字 - @android:style/Theme.DeviceDefault.Light
系统默认明亮样式(亮色系),通常是白底黑字
Android API19支持的样式列表如下:
配置完成保存提交App云端打包后才能生效
注意!!!更改主题时建议使用NoActionBar系列主题。如果配置其他样式主题可能会导致页面顶部多出一个ActionBar UI(actionBar)

APICloud产品与DCloud深度对比分析
> 更新:最新版比较详见:https://ask.dcloud.net.cn/article/36732
========以下为历史内容=========
其实就选型对比而言,不深入看产品,有4点就足矣。
- APICloud反编译和抄袭DCloud代码,已经被北京知识产权法院判决,赔偿DCloud损失并向DCloud道歉。详见。
如此不道德的公司存在是给中国的程序员界丢脸。
而支持、纵容侵权产品,让侵权公司得不到应有惩罚,侵权行为屡禁不止,最终劣币驱逐良币,中国无人创新,最终我们用的软件都是外国写的。
这样的环境,是谁营造的?
其实人人有责。
抵制破解、抄袭、侵权,维护正义、维护中国的软件创新环境,人人有责。
2. DCloud的产品有众多一线互联网公司案例
除了众多创业公司,一线互联网公司如360、大众点评、京东、网易、唯品会、新浪、阿里巴巴也纷纷选择DCloud的工具开发app。
以唯品会、有道词典、大众点评为例,体验完全达到一线互联网公司的苛刻要求。(具体看DCloud官网案例)
这是其他跨平台开发工具所没有取得的成绩,在这些案例的过程中大公司们对DCloud的产品反复提要求,最终打磨出别的产品所不具备的功能和性能。
用DCloud的产品肯定可以达到这种效果,不用DCloud,万一没达到效果,客户和老板问起来:明明你知道DCloud可以,为何冒险用别的?好像很难解释。。。
3. 自卖自夸没用,要看三方有公信力的数据
DCloud的mui和facebook的react native,是当前最主流的跨平台开发工具。
下图是常见跨平台开发工具的百度指数对比。
访问index.baidu.com可以自己看。
蓝色是HBuilder,绿色是mui,紫色是apicloud,非常明显的可以看出DCloud的产品体量远超过apicloud,而且一直在良性增长,而apicloud已经做不起来了。
再补充一个数据,HBuilder已经有200万开发者了,和国外主流的开发ide也达到并驾齐驱的体量。可以自行查HBuilder和sublime、vscode的百度指数对比。
4. 免费免费免费
apicloud等其他国内跨平台工具都是收费的,虽然有免费版本,但是他们的目标还是要把开发者引导成他们的收费客户。
但DCloud是纯免费的,自由的技术产品。没有vip付费用户跟你抢资源,没有用到一定深度就让你付费。
DCloud的唯一的商业变现是你做好app后,如果想推广,可以找DCloud帮你发展用户,如果想广告变现,DCloud有广告平台帮你变现。
我们对自己的定位是,帮助开发者成功,成功做出app,成功运营好app。
5. 扩展性、灵活性、开放性
DCloud的5+SDK、开源mui,都使得任何开发者不会被我们的产品功能约束,都可以自己扩展原生能力,自己修改框架源码。
最后,即使你觉得DCloud的产品仍然不顺手,你也应该去使用react native、weex等干净的产品,而不是支持侵权的apicloud。
作恶的公司得不到抵制,反而被纵容,根本就不会反思,也给产业树立了极坏的样板。
维护产业健康、伸张正义,人人有责!
更新:DCloud新出了终极跨平台框架uni-app,无论功能、性能,apicloud相比毫无优势。
不止是产品,uni-app在文档、技术服务、视频、插件生态上也都秒杀对手。
不要再谈论DCloud的社区不活跃、文档不友好、没有视频培训教程、插件不够多了,这些观点都过时了,都反超apicloud的了
> 更新:最新版比较详见:https://ask.dcloud.net.cn/article/36732
========以下为历史内容=========
其实就选型对比而言,不深入看产品,有4点就足矣。
- APICloud反编译和抄袭DCloud代码,已经被北京知识产权法院判决,赔偿DCloud损失并向DCloud道歉。详见。
如此不道德的公司存在是给中国的程序员界丢脸。
而支持、纵容侵权产品,让侵权公司得不到应有惩罚,侵权行为屡禁不止,最终劣币驱逐良币,中国无人创新,最终我们用的软件都是外国写的。
这样的环境,是谁营造的?
其实人人有责。
抵制破解、抄袭、侵权,维护正义、维护中国的软件创新环境,人人有责。
2. DCloud的产品有众多一线互联网公司案例
除了众多创业公司,一线互联网公司如360、大众点评、京东、网易、唯品会、新浪、阿里巴巴也纷纷选择DCloud的工具开发app。
以唯品会、有道词典、大众点评为例,体验完全达到一线互联网公司的苛刻要求。(具体看DCloud官网案例)
这是其他跨平台开发工具所没有取得的成绩,在这些案例的过程中大公司们对DCloud的产品反复提要求,最终打磨出别的产品所不具备的功能和性能。
用DCloud的产品肯定可以达到这种效果,不用DCloud,万一没达到效果,客户和老板问起来:明明你知道DCloud可以,为何冒险用别的?好像很难解释。。。
3. 自卖自夸没用,要看三方有公信力的数据
DCloud的mui和facebook的react native,是当前最主流的跨平台开发工具。
下图是常见跨平台开发工具的百度指数对比。
访问index.baidu.com可以自己看。
蓝色是HBuilder,绿色是mui,紫色是apicloud,非常明显的可以看出DCloud的产品体量远超过apicloud,而且一直在良性增长,而apicloud已经做不起来了。
再补充一个数据,HBuilder已经有200万开发者了,和国外主流的开发ide也达到并驾齐驱的体量。可以自行查HBuilder和sublime、vscode的百度指数对比。
4. 免费免费免费
apicloud等其他国内跨平台工具都是收费的,虽然有免费版本,但是他们的目标还是要把开发者引导成他们的收费客户。
但DCloud是纯免费的,自由的技术产品。没有vip付费用户跟你抢资源,没有用到一定深度就让你付费。
DCloud的唯一的商业变现是你做好app后,如果想推广,可以找DCloud帮你发展用户,如果想广告变现,DCloud有广告平台帮你变现。
我们对自己的定位是,帮助开发者成功,成功做出app,成功运营好app。
5. 扩展性、灵活性、开放性
DCloud的5+SDK、开源mui,都使得任何开发者不会被我们的产品功能约束,都可以自己扩展原生能力,自己修改框架源码。
最后,即使你觉得DCloud的产品仍然不顺手,你也应该去使用react native、weex等干净的产品,而不是支持侵权的apicloud。
作恶的公司得不到抵制,反而被纵容,根本就不会反思,也给产业树立了极坏的样板。
维护产业健康、伸张正义,人人有责!
更新:DCloud新出了终极跨平台框架uni-app,无论功能、性能,apicloud相比毫无优势。
不止是产品,uni-app在文档、技术服务、视频、插件生态上也都秒杀对手。
不要再谈论DCloud的社区不活跃、文档不友好、没有视频培训教程、插件不够多了,这些观点都过时了,都反超apicloud的了

【分享】淘宝商品评分示例
无图无真相,先看效果图:
接下来是代码实现部分,比较简单,自己看:
HTML 部分
<div class="icons" >
<i data-index="1" class="mui-icon mui-icon-star"></i>
<i data-index="2" class="mui-icon mui-icon-star"></i>
<i data-index="3" class="mui-icon mui-icon-star"></i>
<i data-index="4" class="mui-icon mui-icon-star"></i>
<i data-index="5" class="mui-icon mui-icon-star"></i>
</div>
为每个星星节点添加index索引,方便获取当前所点击元素
JavaScript 部分
mui.init();
mui('.icons').on('click','i',function(){
var index = parseInt(this.getAttribute("data-index"));//获取当前元素的索引值
var parent = this.parentNode;//获取当前元素的父节点
var children = parent.children;//获取父节点下所有子元素
if(this.classList.contains("mui-icon-star")){//判断当前节点列表中是否含有.mui-icon-star元素
for(var i=0;i<index;i ){//亮星
children[i].classList.remove('mui-icon-star');
children[i].classList.add('mui-icon-star-filled');
}
}else{//重置已经亮星的元素
for (var i = index; i < 5; i++ ) {
children[i].classList.add('mui-icon-star')
children[i].classList.remove('mui-icon-star-filled')
}
}
document.getElementById("info").innerHTML = parent.previousElementSibling.innerText ":" index "星好评";
})
已开源,提交至Github,地址: https://github.com/qhhsy/pingfen
无图无真相,先看效果图:
接下来是代码实现部分,比较简单,自己看:
HTML 部分
<div class="icons" >
<i data-index="1" class="mui-icon mui-icon-star"></i>
<i data-index="2" class="mui-icon mui-icon-star"></i>
<i data-index="3" class="mui-icon mui-icon-star"></i>
<i data-index="4" class="mui-icon mui-icon-star"></i>
<i data-index="5" class="mui-icon mui-icon-star"></i>
</div>
为每个星星节点添加index索引,方便获取当前所点击元素
JavaScript 部分
mui.init();
mui('.icons').on('click','i',function(){
var index = parseInt(this.getAttribute("data-index"));//获取当前元素的索引值
var parent = this.parentNode;//获取当前元素的父节点
var children = parent.children;//获取父节点下所有子元素
if(this.classList.contains("mui-icon-star")){//判断当前节点列表中是否含有.mui-icon-star元素
for(var i=0;i<index;i ){//亮星
children[i].classList.remove('mui-icon-star');
children[i].classList.add('mui-icon-star-filled');
}
}else{//重置已经亮星的元素
for (var i = index; i < 5; i++ ) {
children[i].classList.add('mui-icon-star')
children[i].classList.remove('mui-icon-star-filled')
}
}
document.getElementById("info").innerHTML = parent.previousElementSibling.innerText ":" index "星好评";
})
已开源,提交至Github,地址: https://github.com/qhhsy/pingfen
收起阅读 »
有关苹果无法导出p12证书的问题解决办法。
有关苹果无法导出p12 证书的问题解决办法:
很多人刚接触苹果证书的时候感觉很复杂,大部分原因是因为都纯英文,然后再个加上步骤繁琐导致很多同学都不知所措,
就算是出了问题也不知道从何查起。这篇文章不是申请证书的教程,如果找教程请移步 iOS证书(.p12)和描述文件(.mobileprovision)申请或者Google之。
出现问题的截图:
今天就有关无法导出p12证书可能出现的原因做个解释以及解决办法。
原因一
所选类型选择错误。
解决办法:
左侧有两个分类,一个是钥匙串,一个是种类,要选择种类中的我的证书或者证书。然后在右侧证书列表中,右键导出即可。
原因二
使用钥匙串生成的证书有问题,格式为(certSigningRequest)
解决办法:
钥匙串访问--> 证书助理 --> 从证书颁发机构请求证书...
原因三
前两个原因确保没有问题,那么就有可能是Mac系统缺少AppleWWDRCA.cer证书。
解决办法:
这个证书是苹果官方的证书,Apple World Wide Developer Relations Certification Authority
下载地址: Apple PKI
有关苹果无法导出p12 证书的问题解决办法:
很多人刚接触苹果证书的时候感觉很复杂,大部分原因是因为都纯英文,然后再个加上步骤繁琐导致很多同学都不知所措,
就算是出了问题也不知道从何查起。这篇文章不是申请证书的教程,如果找教程请移步 iOS证书(.p12)和描述文件(.mobileprovision)申请或者Google之。
出现问题的截图:
今天就有关无法导出p12证书可能出现的原因做个解释以及解决办法。
原因一
所选类型选择错误。
解决办法:
左侧有两个分类,一个是钥匙串,一个是种类,要选择种类中的我的证书或者证书。然后在右侧证书列表中,右键导出即可。
原因二
使用钥匙串生成的证书有问题,格式为(certSigningRequest)
解决办法:
钥匙串访问--> 证书助理 --> 从证书颁发机构请求证书...
原因三
前两个原因确保没有问题,那么就有可能是Mac系统缺少AppleWWDRCA.cer证书。
解决办法:
这个证书是苹果官方的证书,Apple World Wide Developer Relations Certification Authority
下载地址: Apple PKI

MUI实现actionsheet的自定义样式
大家对于类似于这种效果的社交分享都不陌生,但MUI里没有实现这种效果,官方提供的只能是按钮,样式不能自定义,可能以后会实现样式自定义,但对于目前来说,这种效果还是很急需的。于是自己就想着用5 的窗口遮罩来实现,中间也遇到了好多问题,调试了很长时间,始终效果不理想,虽然用5 的floatWebview实现了遮罩效果,但是点击遮罩部分,并不会使这个分享页面消失。最终在“Dcloud-MUI-CHB”君的指点下用mask:窗口的遮罩实现了。还有一点需要注意的是,分享的时候我们用的logo图标大小不能超过3kb,不然分享直接失败,返回-3.在此分享一下:
<script type="text/javascript">
function openShare() {
shareWebview();
}
mui.plusReady(function() {
ws = plus.webview.currentWebview();
//关闭splash页面;
plus.navigator.closeSplashscreen();
})
var sharew;
var ws = null;
/**
*分享窗口
*/
function shareWebview() {
ws = plus.webview.currentWebview();
if (sharew) { // 避免快速多次点击创建多个窗口
return;
}
var top = plus.display.resolutionHeight - 134;
var href = "share.html";
sharew = plus.webview.create(href, "share.html", {
width: '100%',
height: '134',
top: top,
scrollIndicator: 'none',
scalable: false,
popGesture: 'none'
}, {
shareInfo: {
"url": "test",
"title": "测试",
"content": "测试",
"pageSourceId": ws.id
}
});
sharew.addEventListener("loaded", function() {
sharew.show('slide-in-bottom', 300);
}, false);
// 显示遮罩层
ws.setStyle({
mask: "rgba(0,0,0,0.5)"
});
// 点击关闭遮罩层
ws.addEventListener("maskClick", closeMask, false);
}
function closeMask() {
ws.setStyle({
mask: "none"
});
//避免出现特殊情况,确保分享页面在初始化时关闭
if (!sharew) {
sharew = plus.webview.getWebviewById("share.html");
}
if (sharew) {
sharew.close();
sharew = null;
}
}
</script>
share.html 核心代码
mui.back = function() {
var sourcePage = plus.webview.getWebviewById(pageSourceId);
if (sourcePage) {
sourcePage.evalJS("closeMask()");
}
}
效果图:
源代码在附件share.zip中,可直接在HB中运行。
大家对于类似于这种效果的社交分享都不陌生,但MUI里没有实现这种效果,官方提供的只能是按钮,样式不能自定义,可能以后会实现样式自定义,但对于目前来说,这种效果还是很急需的。于是自己就想着用5 的窗口遮罩来实现,中间也遇到了好多问题,调试了很长时间,始终效果不理想,虽然用5 的floatWebview实现了遮罩效果,但是点击遮罩部分,并不会使这个分享页面消失。最终在“Dcloud-MUI-CHB”君的指点下用mask:窗口的遮罩实现了。还有一点需要注意的是,分享的时候我们用的logo图标大小不能超过3kb,不然分享直接失败,返回-3.在此分享一下:
<script type="text/javascript">
function openShare() {
shareWebview();
}
mui.plusReady(function() {
ws = plus.webview.currentWebview();
//关闭splash页面;
plus.navigator.closeSplashscreen();
})
var sharew;
var ws = null;
/**
*分享窗口
*/
function shareWebview() {
ws = plus.webview.currentWebview();
if (sharew) { // 避免快速多次点击创建多个窗口
return;
}
var top = plus.display.resolutionHeight - 134;
var href = "share.html";
sharew = plus.webview.create(href, "share.html", {
width: '100%',
height: '134',
top: top,
scrollIndicator: 'none',
scalable: false,
popGesture: 'none'
}, {
shareInfo: {
"url": "test",
"title": "测试",
"content": "测试",
"pageSourceId": ws.id
}
});
sharew.addEventListener("loaded", function() {
sharew.show('slide-in-bottom', 300);
}, false);
// 显示遮罩层
ws.setStyle({
mask: "rgba(0,0,0,0.5)"
});
// 点击关闭遮罩层
ws.addEventListener("maskClick", closeMask, false);
}
function closeMask() {
ws.setStyle({
mask: "none"
});
//避免出现特殊情况,确保分享页面在初始化时关闭
if (!sharew) {
sharew = plus.webview.getWebviewById("share.html");
}
if (sharew) {
sharew.close();
sharew = null;
}
}
</script>
share.html 核心代码
mui.back = function() {
var sourcePage = plus.webview.getWebviewById(pageSourceId);
if (sourcePage) {
sourcePage.evalJS("closeMask()");
}
}
效果图:
源代码在附件share.zip中,可直接在HB中运行。 收起阅读 »

关于js对sqlite的支持
看到问题咨询里有一些关于js是否支持Sqlite的问题,这里抛砖引玉。答案是可以支持。
在github上已经有关于这块的代码支持:[https://github.com/kripken/sql.js/](https://github.com/kripken/sql.js/),打开链接地址我们可以看到各种连接办法。例如:node.js,浏览器支持等。
如果我们手上已经有了sqlite的数据库,可以直接添加到我们的app项目中来,通过如下代码方式直接访问:
var xhr = new XMLHttpRequest();
xhr.open('GET', 'assets/test.db', true);//在App中的相对路径
xhr.responseType = 'arraybuffer';
xhr.onload = function(e) {
var uInt8Array = new Uint8Array(this.response);
var db = new SQL.Database(uInt8Array);
var contents = db.exec("SELECT * FROM my_table");//执行查询语句
// contents is now [{columns:['col1','col2',...], values:[[first row], [second row], ...]}]
//查询结果获取办法contents [i].values
};
xhr.send();
看到问题咨询里有一些关于js是否支持Sqlite的问题,这里抛砖引玉。答案是可以支持。
在github上已经有关于这块的代码支持:[https://github.com/kripken/sql.js/](https://github.com/kripken/sql.js/),打开链接地址我们可以看到各种连接办法。例如:node.js,浏览器支持等。
如果我们手上已经有了sqlite的数据库,可以直接添加到我们的app项目中来,通过如下代码方式直接访问:
var xhr = new XMLHttpRequest();
xhr.open('GET', 'assets/test.db', true);//在App中的相对路径
xhr.responseType = 'arraybuffer';
xhr.onload = function(e) {
var uInt8Array = new Uint8Array(this.response);
var db = new SQL.Database(uInt8Array);
var contents = db.exec("SELECT * FROM my_table");//执行查询语句
// contents is now [{columns:['col1','col2',...], values:[[first row], [second row], ...]}]
//查询结果获取办法contents [i].values
};
xhr.send();
收起阅读 »

HTML5+ API文档 CHM精编版
在线文档无索引,搜索不方便,搞了个工具生成~~~
这两天官网都要被我抓烂了哈哈哈哈~~
不多说,文档在附件,全部文件都已离线封装。
split版本为分割子对象、属性为独立页面,方便像我这种记性不好的前进后退查阅,不用再上下滚来滚去找来找去了~~
另外~我把build工具也放出来文档更新可以直接重修build一下大家随意随意~
【update】
5.30 修正部分文档链接错误
在线文档无索引,搜索不方便,搞了个工具生成~~~
这两天官网都要被我抓烂了哈哈哈哈~~
不多说,文档在附件,全部文件都已离线封装。
split版本为分割子对象、属性为独立页面,方便像我这种记性不好的前进后退查阅,不用再上下滚来滚去找来找去了~~
另外~我把build工具也放出来文档更新可以直接重修build一下大家随意随意~
【update】
5.30 修正部分文档链接错误

[分享]简单使用模板,代替字符串拼接。
1.移动互联网应用非常重要的是网络数据的交互,而获取的数据如何转化为我们希望的页面效果,使我们这节课讨论的重点。我们使用固定的数据源做演示。
2.经常会将数据在前台展示,一般情况下,我们会拼接字符串,或者使用第三方提供的模板引擎,这里我们推荐一种简单粗暴的方式(不建议使用到大项目中),但是对于中小型项目可以考虑使用。
其思想和模板引擎的思想类似,没有那么复杂。
直接说如何使用:
①引入JS
②定义模板
③加载数据
④对特殊数据处理(回调函数)
代码中有注释,很容易理解。
html文件
<html>
<head>
<title></title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<link rel="stylesheet" type="text/css" href="../static/styles/mui.min.css" />
<link rel="stylesheet" href="../static/styles/ui-box.css">
<link rel="stylesheet" href="../static/styles/ui-base.css">
<link rel="stylesheet" href="../static/styles/ui-input.css">
<link rel="stylesheet" href="../static/styles/style.css">
<link rel="stylesheet" href="../static/styles/infor.css">
<link rel="stylesheet" type="text/css" href="../static/styles/animate.min.css" />
</head>
<body class="um-vp c-gra1">
<div class="mui-content">
<div class="ub-f1">
<table class='listTable' border='0' cellpadding='0' cellspacing='0' id="cminfo">
</table>
</div>
</div>
</body>
<script src="../static/scripts/mui.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../static/scripts/zy_tmpl.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
(function($, doc) {
$.init();
//$.plusReady(function() {
//数据加载(这里演示就不从后台获取了,直接将获取的数据拿过来)
var data = '[{"id":"43743","cm_id":"0011504030001","cm_areaname":"0.001.001.001.001.003","cm_name":"毕祖辉","cm_tel":"","cm_work_tel":"8570269","cm_color":"10","fphoto":"","cm_sex":"男"},{"id":"43762","cm_id":"0011504030002","cm_areaname":"0.001.001.001.002","cm_name":"严丽华","cm_tel":"","cm_work_tel":"6110357","cm_color":"11","fphoto":"","cm_sex":"女"},{"id":"43709","cm_id":"0011504030001","cm_areaname":"0.001.001.001.001","cm_name":"马强","cm_tel":"","cm_work_tel":"5946083","cm_color":"12","fphoto":"","cm_sex":"男"},{"dataCount":"4731"}]';
//转化为JSON对象
var dataObj = JSON.parse(data);
var dataCount = dataObj.pop();//数据总数量,不是本数据数量(直接忽略)
//定义模板
var t = _t.toString();
var tmp = t.substr(17,t.length-21);
//加载数据 参数解释(模板,数据数量,回调函数[可以不传]);
var res = tmpl(tmp,dataObj,tmpl_count(dataObj),tmpCallBack);
doc.querySelector('#cminfo').innerHTML = res;
//})
function _t(){/*
<tr id='${id}' cm_id='${cm_id}' cm_areaname='${cm_areaname}' style="color:${cb:cm_color}">
<td class="preTd">
<img src='${cb:fphoto}' class='preIcon uc-a2'></td>
<td class="td_name_style">
<div class="td_div">${cm_name}</div>
<p class="ulim">${cb:cm_tel}</p></td>
<td onclick="dialPhone('${cb:cm_tel}')" class='more' width='10%'><img src='../static/imgs/call.png' class='lastIcon'></td>
</tr>
*/}
function tmpCallBack(a,b)
{
switch (b[1]){
case 'cm_tel':
return !isNull(a.cm_tel)?a.cm_work_tel:a.cm_tel;
break;
case "fphoto":
if(!isNull(a.fphoto))
{
var src = a.cm_sex&&~(a.cm_sex).indexOf('女')?"../static/imgs/head-picn.png":"../static/imgs/head-pic.png";
return src;
}else{
return a.fphoto;//如果有则先加载到本地
}
break;
case "cm_color":
return !isNull(a.cm_color)?'':HTMLColor(a.cm_color);
break;
default:
break;
}
return '';
}
//下面的方法可以写为公共的方法
function isNull(value)
{
if(value == null || value == "" || value == "undefined" || value == undefined || value == "null" || value == "(null)" || value == 'NULL' || typeof(value) == 'undefined'){
return false;
}
else{
value = value+"";
value = value.replace(/\s/g,"");
if(value == ""){
return false;
}
return true;
}
}
function HTMLColor(num)
{
var htmlColor = ",Aqua,Black,Blue,Fuchsia,Gray,Green,Lime,Maroon,Navy,Olive,Purple,Red,Silver,Teal,White,Yellow";
var hcs = htmlColor.split(",");
return num > 0 && num < hcs.length ? hcs[num] : '' ;
}
}(mui, document))
</script>
</html>
tmpl.js文件
var tmpl_count=function(dd)
{
if(Object.prototype.toString.apply(dd)==="[object Array]")
{
return dd.length;
}
else
{
var c=0;
for(var i in dd)
c++;
return c;
}
}
var _f = function(d,c,k1,k2,l){
var q = c.match(/(first:|last:)(\"|\'*)([^\"\']*)(\"|\'*)/);
if(!q) return;
if(q[1]==k1){
if(q[2]=='\"'||q[2]=='\''){
return q[3];
}
else
return d[q[3]];
}
else if(q[1]==k2 && l>1)
return "";
}
var t_f = function(t,d,i,l,cb){
return t.replace( /\$\{([^\}]*)\}/g,function(m,c){
if(c.match(/index:/)){
return i;
}
if(c.match(/cb:/) && cb){
return cb(d,c.match(/cb:(.*)/));
}
if(i==0){
var s=_f(d,c,"first:","last:",l);
if(s) return s;
}
if(i==(l-1)){
var s= _f(d,c,"last:","first:",l);
if(s) return s;
}
var ar=c.split('.');
var res=d;
for(var key in ar)
res=res[ar[key]];
return res||"";
});
}
var tmpl = function(t,dd,l,cb,scb){
var r = "";
{
var index=0;
for(var i in dd)
{
if(scb)
scb(0,i,dd[i]);
var rr=t_f(t,dd[i],index,l,cb);
if(scb)
scb(1,rr,dd[i]);
r+=rr;
index++;
}
}
return r;
}
var tmpl_s = function(t,dd,cb)
{
return t_f(t,dd,-1,-1,cb);
}
1.移动互联网应用非常重要的是网络数据的交互,而获取的数据如何转化为我们希望的页面效果,使我们这节课讨论的重点。我们使用固定的数据源做演示。
2.经常会将数据在前台展示,一般情况下,我们会拼接字符串,或者使用第三方提供的模板引擎,这里我们推荐一种简单粗暴的方式(不建议使用到大项目中),但是对于中小型项目可以考虑使用。
其思想和模板引擎的思想类似,没有那么复杂。
直接说如何使用:
①引入JS
②定义模板
③加载数据
④对特殊数据处理(回调函数)
代码中有注释,很容易理解。
html文件
<html>
<head>
<title></title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<link rel="stylesheet" type="text/css" href="../static/styles/mui.min.css" />
<link rel="stylesheet" href="../static/styles/ui-box.css">
<link rel="stylesheet" href="../static/styles/ui-base.css">
<link rel="stylesheet" href="../static/styles/ui-input.css">
<link rel="stylesheet" href="../static/styles/style.css">
<link rel="stylesheet" href="../static/styles/infor.css">
<link rel="stylesheet" type="text/css" href="../static/styles/animate.min.css" />
</head>
<body class="um-vp c-gra1">
<div class="mui-content">
<div class="ub-f1">
<table class='listTable' border='0' cellpadding='0' cellspacing='0' id="cminfo">
</table>
</div>
</div>
</body>
<script src="../static/scripts/mui.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../static/scripts/zy_tmpl.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
(function($, doc) {
$.init();
//$.plusReady(function() {
//数据加载(这里演示就不从后台获取了,直接将获取的数据拿过来)
var data = '[{"id":"43743","cm_id":"0011504030001","cm_areaname":"0.001.001.001.001.003","cm_name":"毕祖辉","cm_tel":"","cm_work_tel":"8570269","cm_color":"10","fphoto":"","cm_sex":"男"},{"id":"43762","cm_id":"0011504030002","cm_areaname":"0.001.001.001.002","cm_name":"严丽华","cm_tel":"","cm_work_tel":"6110357","cm_color":"11","fphoto":"","cm_sex":"女"},{"id":"43709","cm_id":"0011504030001","cm_areaname":"0.001.001.001.001","cm_name":"马强","cm_tel":"","cm_work_tel":"5946083","cm_color":"12","fphoto":"","cm_sex":"男"},{"dataCount":"4731"}]';
//转化为JSON对象
var dataObj = JSON.parse(data);
var dataCount = dataObj.pop();//数据总数量,不是本数据数量(直接忽略)
//定义模板
var t = _t.toString();
var tmp = t.substr(17,t.length-21);
//加载数据 参数解释(模板,数据数量,回调函数[可以不传]);
var res = tmpl(tmp,dataObj,tmpl_count(dataObj),tmpCallBack);
doc.querySelector('#cminfo').innerHTML = res;
//})
function _t(){/*
<tr id='${id}' cm_id='${cm_id}' cm_areaname='${cm_areaname}' style="color:${cb:cm_color}">
<td class="preTd">
<img src='${cb:fphoto}' class='preIcon uc-a2'></td>
<td class="td_name_style">
<div class="td_div">${cm_name}</div>
<p class="ulim">${cb:cm_tel}</p></td>
<td onclick="dialPhone('${cb:cm_tel}')" class='more' width='10%'><img src='../static/imgs/call.png' class='lastIcon'></td>
</tr>
*/}
function tmpCallBack(a,b)
{
switch (b[1]){
case 'cm_tel':
return !isNull(a.cm_tel)?a.cm_work_tel:a.cm_tel;
break;
case "fphoto":
if(!isNull(a.fphoto))
{
var src = a.cm_sex&&~(a.cm_sex).indexOf('女')?"../static/imgs/head-picn.png":"../static/imgs/head-pic.png";
return src;
}else{
return a.fphoto;//如果有则先加载到本地
}
break;
case "cm_color":
return !isNull(a.cm_color)?'':HTMLColor(a.cm_color);
break;
default:
break;
}
return '';
}
//下面的方法可以写为公共的方法
function isNull(value)
{
if(value == null || value == "" || value == "undefined" || value == undefined || value == "null" || value == "(null)" || value == 'NULL' || typeof(value) == 'undefined'){
return false;
}
else{
value = value+"";
value = value.replace(/\s/g,"");
if(value == ""){
return false;
}
return true;
}
}
function HTMLColor(num)
{
var htmlColor = ",Aqua,Black,Blue,Fuchsia,Gray,Green,Lime,Maroon,Navy,Olive,Purple,Red,Silver,Teal,White,Yellow";
var hcs = htmlColor.split(",");
return num > 0 && num < hcs.length ? hcs[num] : '' ;
}
}(mui, document))
</script>
</html>
tmpl.js文件
var tmpl_count=function(dd)
{
if(Object.prototype.toString.apply(dd)==="[object Array]")
{
return dd.length;
}
else
{
var c=0;
for(var i in dd)
c++;
return c;
}
}
var _f = function(d,c,k1,k2,l){
var q = c.match(/(first:|last:)(\"|\'*)([^\"\']*)(\"|\'*)/);
if(!q) return;
if(q[1]==k1){
if(q[2]=='\"'||q[2]=='\''){
return q[3];
}
else
return d[q[3]];
}
else if(q[1]==k2 && l>1)
return "";
}
var t_f = function(t,d,i,l,cb){
return t.replace( /\$\{([^\}]*)\}/g,function(m,c){
if(c.match(/index:/)){
return i;
}
if(c.match(/cb:/) && cb){
return cb(d,c.match(/cb:(.*)/));
}
if(i==0){
var s=_f(d,c,"first:","last:",l);
if(s) return s;
}
if(i==(l-1)){
var s= _f(d,c,"last:","first:",l);
if(s) return s;
}
var ar=c.split('.');
var res=d;
for(var key in ar)
res=res[ar[key]];
return res||"";
});
}
var tmpl = function(t,dd,l,cb,scb){
var r = "";
{
var index=0;
for(var i in dd)
{
if(scb)
scb(0,i,dd[i]);
var rr=t_f(t,dd[i],index,l,cb);
if(scb)
scb(1,rr,dd[i]);
r+=rr;
index++;
}
}
return r;
}
var tmpl_s = function(t,dd,cb)
{
return t_f(t,dd,-1,-1,cb);
}
收起阅读 »

如何安装node.js支持插件
在eclipse插件中,node.js插件中比较知名的是nodeclipse。
从HBuilder6.3起,工具-插件安装,可直接选择nodeclipse插件安装。
安装完毕后重启HBuilder
新建node项目:依次点击菜单文件→新建→其他如下图
5.选择要新建的nodejs项目类型新建项目即可
- 在js文件里提示node.js
注意:nodeclipse的编辑器和HBuilder的编辑器不同。但node.js和web的js均以.js为扩展名,打开js文件时需分清使用哪个js编辑器打开。
一般而言,由于nodeclipse是后安装的,所以.js文件默认以node的编辑器打开,在此编辑器中是不提示HBuilder的语法助手的。
要更换打开方式,在项目管理器里对js文件点右键-打开方式,选择自己想要的编辑器打开。
还可以在菜单里设置永久文件关联,你可以设置你最常使用的方式打开。推荐设置.js文件默认使用HBuilder的js编辑器打开后,然后在打开node.js的js文件时点右键选择nodeclipse编辑器打开。
历史材料归档:
HBuilder6.3以下的版本安装nodeclipse插件的方法如下:
前言,nodeclipse是基于jsdt的,HBuilder没有内置jsdt,如果要安装nodeclipse,则先要安装jsdt插件。
安装JSDT
- 依次点击工具→插件安装→手动安装eclipse插件,点击“可用软件站点”如下图
- 勾选 indigo(注:勾选后,HBuilder启动时会检查indigo已安装的插件是否有升级,从而导致软件启动过慢或者启动后很长时间内比较卡,所以安装完jdt后请将此勾重新去掉)如下图
- 点击确定后,点下拉箭头选择indigo的站点如下图,然后等待加载(此过程有点长,如有设置代理会加快加载速度)
- 加载完毕后,找到programming languages如下图
- 勾选programming languages下的JavaScript Development Tools如下图
6.点击下一步,接受许可协议并安装,安装完毕后重启即可
安装nodeclipse - 依次点击工具→插件安装→浏览eclipse插件市场→搜索node.js→在搜索结果里找nodeclipse如下图
2.点击上图中的install开始加载,加载完毕点下一步接受许可协议静待安装完成即可 - 安装完毕后重启HBuilder
- 新建node项目:依次点击菜单文件→新建→其他如下图
5.选择要新建的nodejs项目类型新建项目即可 - 在js文件里提示node.js
在eclipse插件中,node.js插件中比较知名的是nodeclipse。
从HBuilder6.3起,工具-插件安装,可直接选择nodeclipse插件安装。
安装完毕后重启HBuilder
新建node项目:依次点击菜单文件→新建→其他如下图
5.选择要新建的nodejs项目类型新建项目即可
- 在js文件里提示node.js
注意:nodeclipse的编辑器和HBuilder的编辑器不同。但node.js和web的js均以.js为扩展名,打开js文件时需分清使用哪个js编辑器打开。
一般而言,由于nodeclipse是后安装的,所以.js文件默认以node的编辑器打开,在此编辑器中是不提示HBuilder的语法助手的。
要更换打开方式,在项目管理器里对js文件点右键-打开方式,选择自己想要的编辑器打开。
还可以在菜单里设置永久文件关联,你可以设置你最常使用的方式打开。推荐设置.js文件默认使用HBuilder的js编辑器打开后,然后在打开node.js的js文件时点右键选择nodeclipse编辑器打开。
历史材料归档:
HBuilder6.3以下的版本安装nodeclipse插件的方法如下:
前言,nodeclipse是基于jsdt的,HBuilder没有内置jsdt,如果要安装nodeclipse,则先要安装jsdt插件。
安装JSDT
- 依次点击工具→插件安装→手动安装eclipse插件,点击“可用软件站点”如下图
- 勾选 indigo(注:勾选后,HBuilder启动时会检查indigo已安装的插件是否有升级,从而导致软件启动过慢或者启动后很长时间内比较卡,所以安装完jdt后请将此勾重新去掉)如下图
- 点击确定后,点下拉箭头选择indigo的站点如下图,然后等待加载(此过程有点长,如有设置代理会加快加载速度)
- 加载完毕后,找到programming languages如下图
- 勾选programming languages下的JavaScript Development Tools如下图
6.点击下一步,接受许可协议并安装,安装完毕后重启即可
安装nodeclipse - 依次点击工具→插件安装→浏览eclipse插件市场→搜索node.js→在搜索结果里找nodeclipse如下图
2.点击上图中的install开始加载,加载完毕点下一步接受许可协议静待安装完成即可 - 安装完毕后重启HBuilder
- 新建node项目:依次点击菜单文件→新建→其他如下图
5.选择要新建的nodejs项目类型新建项目即可 - 在js文件里提示node.js

iOS离线打包-友盟统计配置
添加友盟统计插件
注:Linker Flags的添加方法请参考这个文档
-
添加以下静态库:liblibStatistic.a
-
添加以下framework: "UMAnalytics.framework",
"UMCommon.framework", -
添加以下系统库:SystemConfiguration.framework,CoreTelephony.framework, libz.tbd, libsqlite3.tbd
配置友盟统计插件
1.到友盟开放平台申请Appkey
2.打开Info.plist文件找到umeng项,如果没有按图片中的格式添加该项,在下图中的红色区域输入申请的Appkey
注意:
IDFA说明
友盟统计SDK默认采集idfa标识,用来更准确的分析核对数据。对于应用本身没有获取idfa的情况,建议将应用提交至AppStore时按如下方式配置:(以避免被苹果以“应用不含广告功能,但获取了广告标示符IDFA”的而拒绝其上架。))
添加友盟统计插件
注:Linker Flags的添加方法请参考这个文档
-
添加以下静态库:liblibStatistic.a
-
添加以下framework: "UMAnalytics.framework",
"UMCommon.framework", -
添加以下系统库:SystemConfiguration.framework,CoreTelephony.framework, libz.tbd, libsqlite3.tbd
配置友盟统计插件
1.到友盟开放平台申请Appkey
2.打开Info.plist文件找到umeng项,如果没有按图片中的格式添加该项,在下图中的红色区域输入申请的Appkey
注意:
IDFA说明
友盟统计SDK默认采集idfa标识,用来更准确的分析核对数据。对于应用本身没有获取idfa的情况,建议将应用提交至AppStore时按如下方式配置:(以避免被苹果以“应用不含广告功能,但获取了广告标示符IDFA”的而拒绝其上架。))