HBuilderX

HBuilderX

极客开发工具
uni-app

uni-app

开发一次,多端覆盖
uniCloud

uniCloud

云开发平台
HTML5+

HTML5+

增强HTML5的功能体验
MUI

MUI

上万Star的前端框架

Android平台5+ API提前生效,支持在plusready事件前调用

plusready

ios上plus是一直存在的,不涉及等ready事件。但安卓上还是需要等plus ready。
在安卓环境中,通常情况下需要html页面解析完成后才会让5+ API生效,安卓的执行的顺序为:

  1. 加载html页面,loading
  2. 解析html页面(解析title节点、下载script/link等节点引用的资源,如js/css文件)
  3. 触发DOMContentLoaded事件
  4. 触发plusready事件
    此文对执行顺序有详细描述:http://ask.dcloud.net.cn/article/571

这样导致5+ API生效时间比较延后,通常采用以下代码等待plus ready后再调用5+ API:

document.addEventListener('plusready',function () {  
        // 在这里调用5+ API  
},false);

我们总是在不停追求性能优化,生效时间越早,我们可以把app的体验做的更好。
在HBuilder7.5版本之后安卓版支持提前注入5+ API,可以在plusready事件触发之前调用5+ API,操作方法是在页面中添加以下节点:
<script src="html5plus://ready"></script>,示例如下:

<!DOCTYPE html>  
<html>  
    <head>  
        <meta charset="utf-8"/>  
        <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no"/>  
        <title>HTML5+ API</title>  
        <script src="html5plus://ready"></script>  
        <script type="text/javascript" charset="utf-8">  
// 这里可以调用5+ API了,为了更好的兼容性,应该使用以下代码进行判断  
if(window.plus){  
    // 在这里调用5+ API  
}else{// 兼容老版本的plusready事件  
    document.addEventListener('plusready',function () {  
        // 在这里调用5+ API  
    },false);  
}  
        </script>  
    </head>  
    <body>  
Hello HTML5 plus.  
    </body>  
</html>

注意

  1. 5+ API虽然可以提前生效,但为了不引发向下兼容问题,plusready事件并不会提前触发,该事件仍然保持原来的触发时机;
  2. 提前生效的Plus api,操作时需注意,此时DOMContentLoaded事件高概率未触发,此时操作dom会失败,操作dom也还是得等到DOMContentLoaded后;
  3. Android3.0及以上平台才支持提前生效,Android2.*版本不支持此功能;

应用场景举例

  • 定位
    很多app的页面是根据位置来显示内容的,如果在DOMContentLoaded后再请求位置,然后再提交服务器获取该位置周边的商家列表,这样就会慢。而提前使用plus api获取位置,就可以加速页面显示速度。尤其对于首页就要拉周边信息的app更重要。
  • 父子页面加载
    如果页面是父子webview布局,过去是父页面在触发plusready后再创建子页面,导致整体页面显出出来比较慢。如果让plus api提前生效,我们可以无需等待父页面plusready就直接创建子页面。
    另外,HBuilder在2017年起的版本,支持双首页,如果首页是父子页面,建议把这2个页面都配到manifest里形成双首页,此时原来的子页面并不需要等父页面的plus ready才创建。而非首页的二级页面,其实也不建议用父子页面,而是使用nativeobj里的原生view来做title,不用webview来做title。

应用场景还有很多,优化无极限,欢迎高手继续研究。

继续阅读 »

ios上plus是一直存在的,不涉及等ready事件。但安卓上还是需要等plus ready。
在安卓环境中,通常情况下需要html页面解析完成后才会让5+ API生效,安卓的执行的顺序为:

  1. 加载html页面,loading
  2. 解析html页面(解析title节点、下载script/link等节点引用的资源,如js/css文件)
  3. 触发DOMContentLoaded事件
  4. 触发plusready事件
    此文对执行顺序有详细描述:http://ask.dcloud.net.cn/article/571

这样导致5+ API生效时间比较延后,通常采用以下代码等待plus ready后再调用5+ API:

document.addEventListener('plusready',function () {  
        // 在这里调用5+ API  
},false);

我们总是在不停追求性能优化,生效时间越早,我们可以把app的体验做的更好。
在HBuilder7.5版本之后安卓版支持提前注入5+ API,可以在plusready事件触发之前调用5+ API,操作方法是在页面中添加以下节点:
<script src="html5plus://ready"></script>,示例如下:

<!DOCTYPE html>  
<html>  
    <head>  
        <meta charset="utf-8"/>  
        <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no"/>  
        <title>HTML5+ API</title>  
        <script src="html5plus://ready"></script>  
        <script type="text/javascript" charset="utf-8">  
// 这里可以调用5+ API了,为了更好的兼容性,应该使用以下代码进行判断  
if(window.plus){  
    // 在这里调用5+ API  
}else{// 兼容老版本的plusready事件  
    document.addEventListener('plusready',function () {  
        // 在这里调用5+ API  
    },false);  
}  
        </script>  
    </head>  
    <body>  
Hello HTML5 plus.  
    </body>  
</html>

注意

  1. 5+ API虽然可以提前生效,但为了不引发向下兼容问题,plusready事件并不会提前触发,该事件仍然保持原来的触发时机;
  2. 提前生效的Plus api,操作时需注意,此时DOMContentLoaded事件高概率未触发,此时操作dom会失败,操作dom也还是得等到DOMContentLoaded后;
  3. Android3.0及以上平台才支持提前生效,Android2.*版本不支持此功能;

应用场景举例

  • 定位
    很多app的页面是根据位置来显示内容的,如果在DOMContentLoaded后再请求位置,然后再提交服务器获取该位置周边的商家列表,这样就会慢。而提前使用plus api获取位置,就可以加速页面显示速度。尤其对于首页就要拉周边信息的app更重要。
  • 父子页面加载
    如果页面是父子webview布局,过去是父页面在触发plusready后再创建子页面,导致整体页面显出出来比较慢。如果让plus api提前生效,我们可以无需等待父页面plusready就直接创建子页面。
    另外,HBuilder在2017年起的版本,支持双首页,如果首页是父子页面,建议把这2个页面都配到manifest里形成双首页,此时原来的子页面并不需要等父页面的plus ready才创建。而非首页的二级页面,其实也不建议用父子页面,而是使用nativeobj里的原生view来做title,不用webview来做title。

应用场景还有很多,优化无极限,欢迎高手继续研究。

收起阅读 »

精华: HTML5 用 websql 模仿 localStorage 几乎无大小限制,比localStorage和plus.storage更加实用 by 刘涛

2016-09-25  

websql_localStorage_liutao.js:  用 websql 模仿 localStorage 无大小限制  

websql操作来自网上资料,经过增强改进 , by liutao qq 30234923  
    数据库操作辅助类,定义对象、数据操作方法都在这里定义  

表 kv 三个字段: (k,v,更新时间)  
以下 kv 函数 会自动打开 数据库,建表 等等,简单调用即可  
注意 websql 为异步,你不能指望 setItem 后,下一句立刻就可以获取 变化后 的值。须在 回调函数 中继续下一句  

1.  
websql_exesql('delete from kv where k=?', ['小红']); // ['小红','a','b']  
websql_exesql(' delete from kv where k=\'小红\'; ');  
websql_exesql('CREATE INDEX IF NOT EXISTS idx_kv_k ON kv(k);');  
websql_exesql('CREATE INDEX IF NOT EXISTS idx_kv_k ON kv(k);', [], function(){  
    alert('搞定');  
});  

2.  
websql_localStorage_getItem('小红', function(k,v,更新时间,此k记录数){  
    alert( '\n' + k + '\n\n' + v + '\n\n' + 更新时间 );  

    if( 此k记录数 > 1 )  
        alert('不正常但未错: websql_localStorage_getItem: k=['+ k +'], 此k对应的记录数 = ' + 此k记录数);  
});  

3.  
websql_localStorage_setItem('小红', '嘿嘿嘿4');  
websql_localStorage_setItem('小红', '嘿嘿嘿3', function(k,v,更新时间){  
    alert( '\n' + k + '\n\n' + v + '\n\n' + 更新时间 );  
});  

4.  
websql_localStorage_removeItem('小红');  
websql_localStorage_removeItem('小红', function(k){  
    alert( '\n' + k + '\n\n' );  
});  

5.  
websql_localStorage_length( function(length){  
    alert( '\n websql_localStorage_length = ' + length + '\n\n' );  
});  

6.  
websql_localStorage_clear();  
继续阅读 »
2016-09-25  

websql_localStorage_liutao.js:  用 websql 模仿 localStorage 无大小限制  

websql操作来自网上资料,经过增强改进 , by liutao qq 30234923  
    数据库操作辅助类,定义对象、数据操作方法都在这里定义  

表 kv 三个字段: (k,v,更新时间)  
以下 kv 函数 会自动打开 数据库,建表 等等,简单调用即可  
注意 websql 为异步,你不能指望 setItem 后,下一句立刻就可以获取 变化后 的值。须在 回调函数 中继续下一句  

1.  
websql_exesql('delete from kv where k=?', ['小红']); // ['小红','a','b']  
websql_exesql(' delete from kv where k=\'小红\'; ');  
websql_exesql('CREATE INDEX IF NOT EXISTS idx_kv_k ON kv(k);');  
websql_exesql('CREATE INDEX IF NOT EXISTS idx_kv_k ON kv(k);', [], function(){  
    alert('搞定');  
});  

2.  
websql_localStorage_getItem('小红', function(k,v,更新时间,此k记录数){  
    alert( '\n' + k + '\n\n' + v + '\n\n' + 更新时间 );  

    if( 此k记录数 > 1 )  
        alert('不正常但未错: websql_localStorage_getItem: k=['+ k +'], 此k对应的记录数 = ' + 此k记录数);  
});  

3.  
websql_localStorage_setItem('小红', '嘿嘿嘿4');  
websql_localStorage_setItem('小红', '嘿嘿嘿3', function(k,v,更新时间){  
    alert( '\n' + k + '\n\n' + v + '\n\n' + 更新时间 );  
});  

4.  
websql_localStorage_removeItem('小红');  
websql_localStorage_removeItem('小红', function(k){  
    alert( '\n' + k + '\n\n' );  
});  

5.  
websql_localStorage_length( function(length){  
    alert( '\n websql_localStorage_length = ' + length + '\n\n' );  
});  

6.  
websql_localStorage_clear();  
收起阅读 »

绝对路径的事情

HBuilder

在html页面里用完整的相对路径包含静态资源:<javascript src="http://localhost:13131/js/test.js"> <javascript src="http://localhost:13131/img/test.jpg">。总算搞定了 h5 转 APP各种繁琐问题。 这个写法android和ios 都可以吗?

继续阅读 »

在html页面里用完整的相对路径包含静态资源:<javascript src="http://localhost:13131/js/test.js"> <javascript src="http://localhost:13131/img/test.jpg">。总算搞定了 h5 转 APP各种繁琐问题。 这个写法android和ios 都可以吗?

收起阅读 »

利用流量防火墙巧妙禁用更新、安装插件两不误

由于最新版对php方面存在一些bug,导致使用php的我感觉效率大大降低了。
由于这软件解压后运行会自动进行升级,旧的版本很快就本最新版替换了。
我试了几次解压旧版,用一次重新打开就要再次解压旧版,好烦。
没有找到怎么设置不自动更新选项。
打开火绒安全软件,流量防火墙中发现rcp.exe流量下载全速,这就是hbuilder的,用了联网使用。
于是灵机一动,将其网速限制,禁止联网。

果然可以阻止自动更新了,打开自动检测后提示检测更新失败。
这时候可以进行插件安装了,选择需要安装的插件,然后进行安装。
记得此时把联网控制关闭,让其联网,下载安装好插件后提示重新启动Hbuilder,启动后发现插件没有问题了。
一看流量防火墙中rcp又全速下载了,进行禁止器联网后一切正常。
这个方法在检测更新时会慢一点,有点耐心就行了,过了这会随自己这么玩。

附件有图片教程

继续阅读 »

由于最新版对php方面存在一些bug,导致使用php的我感觉效率大大降低了。
由于这软件解压后运行会自动进行升级,旧的版本很快就本最新版替换了。
我试了几次解压旧版,用一次重新打开就要再次解压旧版,好烦。
没有找到怎么设置不自动更新选项。
打开火绒安全软件,流量防火墙中发现rcp.exe流量下载全速,这就是hbuilder的,用了联网使用。
于是灵机一动,将其网速限制,禁止联网。

果然可以阻止自动更新了,打开自动检测后提示检测更新失败。
这时候可以进行插件安装了,选择需要安装的插件,然后进行安装。
记得此时把联网控制关闭,让其联网,下载安装好插件后提示重新启动Hbuilder,启动后发现插件没有问题了。
一看流量防火墙中rcp又全速下载了,进行禁止器联网后一切正常。
这个方法在检测更新时会慢一点,有点耐心就行了,过了这会随自己这么玩。

附件有图片教程

收起阅读 »

打包后和真机调试 不能达到同样的效果

真机调试 各种功能 都实现了 打包成apk后 有几个功能 就不管用了 这怎么回事?

真机调试 各种功能 都实现了 打包成apk后 有几个功能 就不管用了 这怎么回事?

android触摸提示音

现有一个项目需要点击有回馈提示 自己看了看ANDROID API 写了出来 见很多人需要分享出来大家学习学习

var context = null;  
if(mui.os.android){  
            if(context == null){  
                plus.android.importClass("android.media.AudioManager");  
                context = plus.android.importClass("android.content.Context");  
                    var RingtoneManager = plus.android.runtimeMainActivity().getSystemService(context.AUDIO_SERVICE);  
                RingtoneManager.playSoundEffect(1);  
            }else{  
                var RingtoneManager = plus.android.runtimeMainActivity().getSystemService(context.AUDIO_SERVICE);  
                RingtoneManager.playSoundEffect(1);   
            }  

        }  

plus.device.vibrate( 50 ); //震动
继续阅读 »

现有一个项目需要点击有回馈提示 自己看了看ANDROID API 写了出来 见很多人需要分享出来大家学习学习

var context = null;  
if(mui.os.android){  
            if(context == null){  
                plus.android.importClass("android.media.AudioManager");  
                context = plus.android.importClass("android.content.Context");  
                    var RingtoneManager = plus.android.runtimeMainActivity().getSystemService(context.AUDIO_SERVICE);  
                RingtoneManager.playSoundEffect(1);  
            }else{  
                var RingtoneManager = plus.android.runtimeMainActivity().getSystemService(context.AUDIO_SERVICE);  
                RingtoneManager.playSoundEffect(1);   
            }  

        }  

plus.device.vibrate( 50 ); //震动
收起阅读 »

在红米note2 mui8上子选项卡偶尔遮盖部分底部导航栏

mui

经测试发现去掉这句话就没事了 plus.webview.currentWebview().setStyle({scrollIndicator:'none'}); 不知道是什么原因

经测试发现去掉这句话就没事了 plus.webview.currentWebview().setStyle({scrollIndicator:'none'}); 不知道是什么原因

iOS10 降级到 iOS9

最近手机升级到iOS10后无法连接调试,现在只能讲手机系统降级到iOS9,为了帮助大家,讲降级方法分享
如下:

  1. 需要电脑安装iTools和iTunes
  2. 连接手机
  3. 在iTools下载手机对应的固件文件
  4. 通过iTunes安装固件文件(按住Shift键点击“更新”按钮选择固件文件)

继续阅读 »

最近手机升级到iOS10后无法连接调试,现在只能讲手机系统降级到iOS9,为了帮助大家,讲降级方法分享
如下:

  1. 需要电脑安装iTools和iTunes
  2. 连接手机
  3. 在iTools下载手机对应的固件文件
  4. 通过iTunes安装固件文件(按住Shift键点击“更新”按钮选择固件文件)

收起阅读 »

发现真机测试困扰太多,建立了群,还请无私的各位能互相帮忙测试APP

你在开发app后,如何测试各种机型的呢,找朋友,找同事,有限的几种机型吧。
公司购买测试设备,成本太大。
客户反映其他机型有问题,你怎么办,

有这个想法,就组建了个qq群,方便真机测试,还请加群的朋友互相帮忙。
群号:102920834

你在开发app后,如何测试各种机型的呢,找朋友,找同事,有限的几种机型吧。
公司购买测试设备,成本太大。
客户反映其他机型有问题,你怎么办,

有这个想法,就组建了个qq群,方便真机测试,还请加群的朋友互相帮忙。
群号:102920834

关于HBuilder语法验证的建议

HBuilder

HBuilder自带的JS语法验证无法正常解析ES6的语法(比如箭头函数报错), 建议迁移到node插件eslint

HBuilder自带的JS语法验证无法正常解析ES6的语法(比如箭头函数报错), 建议迁移到node插件eslint

【分享】mui switch开关设置为只读效果

switch mui

昨天提问,没人啊没人,所谓的只读就是要求去除点击效果,只运行js后台操作。
研究了下Mui.js后,如下:

当然,希望官方加入readonly属性!

1.重新定义mui-disable,取消透明样式,当然也可以在这里改变switch的颜色background-color

        .mui-switch.mui-disabled{  
            opacity:99;  
        }

PS,改变颜色:

        .mui-switch.mui-active.mui-disabled{  
            background-color:#eac;  
            border-color:#eac;  
            opacity:99;  
        }

2.在需要的的switch处加入mui-disabled属性

                    <div id="sw1" class="mui-switch mui-active mui-disabled" >  
                        <div class="mui-switch-handle" ></div>  
                    </div>

3.在代码中复制toggle方法并hook掉原来的toggle

        mui.ready(function() {  
            mui("#sw1").switch().oldtoggle = mui("#sw1").switch().toggle;  
            mui("#sw1").switch().toggle = function(){  
            };  
        });

4.在需要后台js操作的地方,调用新的toggle就可以了,同时你会发现点击该switch会失去效果。

        function tg(){  
            mui("#sw1").switch().oldtoggle();  
        };

5.大概就像附件这样!欢迎加分。

继续阅读 »

昨天提问,没人啊没人,所谓的只读就是要求去除点击效果,只运行js后台操作。
研究了下Mui.js后,如下:

当然,希望官方加入readonly属性!

1.重新定义mui-disable,取消透明样式,当然也可以在这里改变switch的颜色background-color

        .mui-switch.mui-disabled{  
            opacity:99;  
        }

PS,改变颜色:

        .mui-switch.mui-active.mui-disabled{  
            background-color:#eac;  
            border-color:#eac;  
            opacity:99;  
        }

2.在需要的的switch处加入mui-disabled属性

                    <div id="sw1" class="mui-switch mui-active mui-disabled" >  
                        <div class="mui-switch-handle" ></div>  
                    </div>

3.在代码中复制toggle方法并hook掉原来的toggle

        mui.ready(function() {  
            mui("#sw1").switch().oldtoggle = mui("#sw1").switch().toggle;  
            mui("#sw1").switch().toggle = function(){  
            };  
        });

4.在需要后台js操作的地方,调用新的toggle就可以了,同时你会发现点击该switch会失去效果。

        function tg(){  
            mui("#sw1").switch().oldtoggle();  
        };

5.大概就像附件这样!欢迎加分。

收起阅读 »

使用mui的索引列表demo,动态加载,修改为通讯录联系人。

因公司需要,本人从安卓开发转战h5开发,若有不对指出,请指出,请勿喷!这是我在自学过程,开发公司项目遇到的问题。
按照之前论坛已经有大神给出 修改 mui.indexedlist.js对应部分为
init: function(holder, options) {
var self = this;
mui.ajax('url', {//
data: {
},
dataType: 'json', //服务器返回json格式数据
type: 'post', //HTTP请求类型
timeout: 10000, //超时时间设置为10秒;
success: function(data) {
var table = document.body.querySelector('.mui-table-view');
var html="",
for (var i = 0; i < data.length; i++) {
//插入数据
html= "你需要的数据";
}
table.innerHTML = html;
self.init1(holder, options);
},
error: function(xhr, type, errorThrown) {
console.log(type);
}
});
},
init1: function(holder, options) {
var self = this;
self.options = options || {};
self.box = holder;
if (!self.box) {
throw "实例 IndexedList 时需要指定 element";
}
self.createDom();
self.findElements();
self.caleLayout();
self.bindEvent();
},

即可发现数据就加载列表上了。 如果你的 数据源 已经安装 字母顺序分好类 ,按照demo 中 分别将数据 添加到对应的
<li data-group="A" class="mui-table-view-divider mui-indexed-list-group">A</li>   下面即可。
如果数据源没有进行分类,例如数据源如下格式:{"cRealName":"XX","cTelephoneNumber":"137xxxxxxxxx","cDepartmentName":"董事长办公室"}
这是项目中后台给我返回的数据源。 几经周折我如下 修改 完成项目需求。
var table = document.body.querySelector('.mui-table-view');
var htmla=""; //一个字母创建一个 ,即可
var b=0,a=0;//
for (var i = 0; i < data.length; i++) {
//插入数据
var s=makePy(data[i].cRealName)+"";//此方法为 将返回的姓名 转为 大写首字母缩写 ,百度即可 如 李二 转为LR
var shouzimu=s.substr(0, 1); //此方法获取 首字母 。
//首字母 为 A的
if(shouzimu=="A"){
if (a==0) {
htmla += '<li data-group="A" class="mui-table-view-divider mui-indexed-list-group">A</li> <li data-value='+s+ 'data-tags='+s+' class="mui-table-view-cell mui-indexed-list-item">'+data[i].cRealName+'</li>';
a=a+1;
} else{
htmla +='<li data-value='+s+ 'data-tags='+s+' class="mui-table-view-cell mui-indexed-list-item">'+data[i].cRealName+'</li>';
}
} 
}
table.innerHTML = htmla;//要按照 字母顺序添加 对应字母的 字符串即可
self.init1(holder, options);
这样不管数据源如何返回 都会按照首字母 排序下来。

继续阅读 »

因公司需要,本人从安卓开发转战h5开发,若有不对指出,请指出,请勿喷!这是我在自学过程,开发公司项目遇到的问题。
按照之前论坛已经有大神给出 修改 mui.indexedlist.js对应部分为
init: function(holder, options) {
var self = this;
mui.ajax('url', {//
data: {
},
dataType: 'json', //服务器返回json格式数据
type: 'post', //HTTP请求类型
timeout: 10000, //超时时间设置为10秒;
success: function(data) {
var table = document.body.querySelector('.mui-table-view');
var html="",
for (var i = 0; i < data.length; i++) {
//插入数据
html= "你需要的数据";
}
table.innerHTML = html;
self.init1(holder, options);
},
error: function(xhr, type, errorThrown) {
console.log(type);
}
});
},
init1: function(holder, options) {
var self = this;
self.options = options || {};
self.box = holder;
if (!self.box) {
throw "实例 IndexedList 时需要指定 element";
}
self.createDom();
self.findElements();
self.caleLayout();
self.bindEvent();
},

即可发现数据就加载列表上了。 如果你的 数据源 已经安装 字母顺序分好类 ,按照demo 中 分别将数据 添加到对应的
<li data-group="A" class="mui-table-view-divider mui-indexed-list-group">A</li>   下面即可。
如果数据源没有进行分类,例如数据源如下格式:{"cRealName":"XX","cTelephoneNumber":"137xxxxxxxxx","cDepartmentName":"董事长办公室"}
这是项目中后台给我返回的数据源。 几经周折我如下 修改 完成项目需求。
var table = document.body.querySelector('.mui-table-view');
var htmla=""; //一个字母创建一个 ,即可
var b=0,a=0;//
for (var i = 0; i < data.length; i++) {
//插入数据
var s=makePy(data[i].cRealName)+"";//此方法为 将返回的姓名 转为 大写首字母缩写 ,百度即可 如 李二 转为LR
var shouzimu=s.substr(0, 1); //此方法获取 首字母 。
//首字母 为 A的
if(shouzimu=="A"){
if (a==0) {
htmla += '<li data-group="A" class="mui-table-view-divider mui-indexed-list-group">A</li> <li data-value='+s+ 'data-tags='+s+' class="mui-table-view-cell mui-indexed-list-item">'+data[i].cRealName+'</li>';
a=a+1;
} else{
htmla +='<li data-value='+s+ 'data-tags='+s+' class="mui-table-view-cell mui-indexed-list-item">'+data[i].cRealName+'</li>';
}
} 
}
table.innerHTML = htmla;//要按照 字母顺序添加 对应字母的 字符串即可
self.init1(holder, options);
这样不管数据源如何返回 都会按照首字母 排序下来。

收起阅读 »