HBuilderX

HBuilderX

极客开发工具
uni-app

uni-app

开发一次,多端覆盖
uniCloud

uniCloud

云开发平台
HTML5+

HTML5+

增强HTML5的功能体验
MUI

MUI

上万Star的前端框架

列表页面 跳转到详情页面 如何让列表页面刷新 我所用的方法

mui

比如一个待办列表 我们点击进入详情页面后进行操作 就会返回列表页面然后再次刷新列表

呃... 我琢磨了俩个方法

第一个就是

var taskList = plus.webview.getWebviewById('跳转页面ID');  
                taskList.reload();  
                mui.back();  

mui.openWindow({  
                url:'跳转页面url',  
                id:'跳转页面ID',  
                });

这个大家应该知道滴 方便又快捷 操作完后页面确实刷新了

这个方法在http://ask.dcloud.net.cn/article/617有详细介绍

然而我发现安卓4.0的版本 还是华为手机操作系统的问题 用这个方法后返回列表页面居然卡死了

于是我使用自定义事件进行跳转

详情页面

...

var taskList = plus.webview.getWebviewById('跳转页面ID');
mui.fire(跳转页面ID,'自定义事件名称');

mui.openWindow({
url:'跳转页面url',
id:'跳转页面ID',
});
...

列表页面

...
window.addEventListener('自定义事件',function(){
触发事件。。。
});
...

不过用自定义事件后 可能还有许多问题要处理 比如列表之前页面传过来的值并会变成undefined 不过相信大家应该可以轻松解决

其实我还是一只菜鸡 发文章就想赚点积分 看看文章回复下人家 不知道怎么积分就突然变负了 希望大家捧捧场 嘿嘿

继续阅读 »

比如一个待办列表 我们点击进入详情页面后进行操作 就会返回列表页面然后再次刷新列表

呃... 我琢磨了俩个方法

第一个就是

var taskList = plus.webview.getWebviewById('跳转页面ID');  
                taskList.reload();  
                mui.back();  

mui.openWindow({  
                url:'跳转页面url',  
                id:'跳转页面ID',  
                });

这个大家应该知道滴 方便又快捷 操作完后页面确实刷新了

这个方法在http://ask.dcloud.net.cn/article/617有详细介绍

然而我发现安卓4.0的版本 还是华为手机操作系统的问题 用这个方法后返回列表页面居然卡死了

于是我使用自定义事件进行跳转

详情页面

...

var taskList = plus.webview.getWebviewById('跳转页面ID');
mui.fire(跳转页面ID,'自定义事件名称');

mui.openWindow({
url:'跳转页面url',
id:'跳转页面ID',
});
...

列表页面

...
window.addEventListener('自定义事件',function(){
触发事件。。。
});
...

不过用自定义事件后 可能还有许多问题要处理 比如列表之前页面传过来的值并会变成undefined 不过相信大家应该可以轻松解决

其实我还是一只菜鸡 发文章就想赚点积分 看看文章回复下人家 不知道怎么积分就突然变负了 希望大家捧捧场 嘿嘿

收起阅读 »

页面返回后自动跳转到对应的slider,用slider.gotoPage()可以解决

tab mui

点击列表的时候把当前的tab存到sessionStorage里面,返回的时候取出来,然后判断currentTab的值

var slider = $('#slider').slider();
//
if(currentTab=='0'){

            slider.gotoPage(0,100);  

        }else if(currentTab=='1'){  

            slider.gotoPage(1,100);  

        }else if(currentTab=='2'){  

            slider.gotoPage(2,100);   

        }else if(currentTab=='3'){  

            slider.gotoPage(3,100);  
        }
继续阅读 »

点击列表的时候把当前的tab存到sessionStorage里面,返回的时候取出来,然后判断currentTab的值

var slider = $('#slider').slider();
//
if(currentTab=='0'){

            slider.gotoPage(0,100);  

        }else if(currentTab=='1'){  

            slider.gotoPage(1,100);  

        }else if(currentTab=='2'){  

            slider.gotoPage(2,100);   

        }else if(currentTab=='3'){  

            slider.gotoPage(3,100);  
        }
收起阅读 »

上传多张照片到服务器

        var server = **********; //上传文件的端口  
        var files = []; //文件的数组  
        document.getElementById("ContractID-btn").addEventListener('tap', function() {  
            plus.gallery.pick(function(e) {  
                document.getElementById("ContractID-btn").innerText = '选择照片(' + e.files.length + ')张';  
                //从相册添加文件  
                appendFile(e); //添加文件  
            }, function(e) {  
                // outSet("取消选择图片");  
            }, {  
                filter: "image",  
                multiple: true,  
                system: false  
            });  
        });  
        //上传文件  
        function uploadContract() {  
            var task = plus.uploader.createUpload(server, {  
                method: "POST"  
            }, function(t, status) {  
                if(status == 200) {  
                    plus.nativeUI.closeWaiting();  
                    mui.toast('上传成功');  
                    ContractZIP = JSON.parse(t.responseText).fileName;  
                    rowContract = JSON.parse(t.responseText).rawFiles;  
                } else {  
                    alert('上传失败,请重试');  
                }  
            });  
            task.addData("fileType", "合同");  
            task.addData("customerId", CustomerId);  
            for(var i = 0; i < files.length; i++) {  
                var f = files[i];  
                task.addFile(f.path, {  
                    key: f.name  
                });  
            }  
            task.start();  
        }  
        //添加文件            
        function appendFile(p) {  
            plus.nativeUI.showWaiting("正在上传...");  
            var index = 1;  
            files = []; //清空数组,防止重复上传  
            for(var i = 0; i < p.files.length; i++) {  
                var n = p.files[i].substr(p.files[i].lastIndexOf('/') + 1);  
                files.push({  
                    name: "uploadkey" + index,  
                    path: p.files[i]  
                });  
                index++;  
            }  
            uploadContract();//添加完文件,开始上传  
        }
继续阅读 »
        var server = **********; //上传文件的端口  
        var files = []; //文件的数组  
        document.getElementById("ContractID-btn").addEventListener('tap', function() {  
            plus.gallery.pick(function(e) {  
                document.getElementById("ContractID-btn").innerText = '选择照片(' + e.files.length + ')张';  
                //从相册添加文件  
                appendFile(e); //添加文件  
            }, function(e) {  
                // outSet("取消选择图片");  
            }, {  
                filter: "image",  
                multiple: true,  
                system: false  
            });  
        });  
        //上传文件  
        function uploadContract() {  
            var task = plus.uploader.createUpload(server, {  
                method: "POST"  
            }, function(t, status) {  
                if(status == 200) {  
                    plus.nativeUI.closeWaiting();  
                    mui.toast('上传成功');  
                    ContractZIP = JSON.parse(t.responseText).fileName;  
                    rowContract = JSON.parse(t.responseText).rawFiles;  
                } else {  
                    alert('上传失败,请重试');  
                }  
            });  
            task.addData("fileType", "合同");  
            task.addData("customerId", CustomerId);  
            for(var i = 0; i < files.length; i++) {  
                var f = files[i];  
                task.addFile(f.path, {  
                    key: f.name  
                });  
            }  
            task.start();  
        }  
        //添加文件            
        function appendFile(p) {  
            plus.nativeUI.showWaiting("正在上传...");  
            var index = 1;  
            files = []; //清空数组,防止重复上传  
            for(var i = 0; i < p.files.length; i++) {  
                var n = p.files[i].substr(p.files[i].lastIndexOf('/') + 1);  
                files.push({  
                    name: "uploadkey" + index,  
                    path: p.files[i]  
                });  
                index++;  
            }  
            uploadContract();//添加完文件,开始上传  
        }
收起阅读 »

设置数字键盘的方法

<input type="number" pattern="\d*"/>

<input type="number" pattern="\d*"/>

我觉得这个启动时间优化空间很大!

性能优化

我觉得这个启动时间优化空间很大!

比我的Dreamweaver cs5 打开都慢很多!

我觉得这个启动时间优化空间很大!

比我的Dreamweaver cs5 打开都慢很多!

【示例】 Mui v3.3.0使用dialog实现密码的输入及验证

弹出框 技术分享 mui

需求描述

使用dialog弹出密码输入框,用户输入密码并且密码验证通过后方可关闭dialog。

需求分析

首先,dialog中提供密码输入框。
其次,用户输入密码后对密码进行验证。
最后,通过验证则关闭dialog,否则不关闭dialog并提示错误信息。

实现思路

dialog

mui提供了许多dialog,只有mui.prompt()提供了输入框,但它并不是密码框。
mui.confirm()的message参数,可以传html代码段来展示密码框,就选它了。

回调函数

由于当前版本mui,点击dialog中的按钮均会关闭dialog,所以需要对dialog按钮的默认行为进行修改。
注:下个版本会更新此修改,目前需要的话请下载附件中的mui.js文件。

验证密码

对用户输入的密码进行验证后,如果验证失败,则需要做出相应的提示。
和密码框的思路一样,使用一个文本内容默认为空的元素来展示错误信息。

功能实现

密码输入框

使用mui.confirm()弹出密码输入框。

mui.confirm('<input type="password" id="test" />', 'Hello MUI', null, function(e) {},'div');  

注:这里需要声明使用H5模式的dialog,参考文档dialog

阻止关闭dialog

用户输入完成后,点击”确认“按钮,验证密码。

mui.confirm('<input type="password" id="test" />', 'Hello MUI', null, function(event) {  
    var index = event.index;  
    if(index === 1) {  
        var pwd = document.getElementById('test').value;  
        // 验证失败返回false  
        return false;  
    }  
},'div');  

修改按钮的默认行为后,在回调函数中返回false,则不会关闭dialog。

错误信息

在拼接密码输入框的同时,见错误信息提示的元素一起拼接。

mui.confirm('<input type="password" id="test" /><span id="error">&nbsp</span>', 'Hello MUI', null, function(event) {},'div');  

源码

附上源码,直接浏览即可。

继续阅读 »

需求描述

使用dialog弹出密码输入框,用户输入密码并且密码验证通过后方可关闭dialog。

需求分析

首先,dialog中提供密码输入框。
其次,用户输入密码后对密码进行验证。
最后,通过验证则关闭dialog,否则不关闭dialog并提示错误信息。

实现思路

dialog

mui提供了许多dialog,只有mui.prompt()提供了输入框,但它并不是密码框。
mui.confirm()的message参数,可以传html代码段来展示密码框,就选它了。

回调函数

由于当前版本mui,点击dialog中的按钮均会关闭dialog,所以需要对dialog按钮的默认行为进行修改。
注:下个版本会更新此修改,目前需要的话请下载附件中的mui.js文件。

验证密码

对用户输入的密码进行验证后,如果验证失败,则需要做出相应的提示。
和密码框的思路一样,使用一个文本内容默认为空的元素来展示错误信息。

功能实现

密码输入框

使用mui.confirm()弹出密码输入框。

mui.confirm('<input type="password" id="test" />', 'Hello MUI', null, function(e) {},'div');  

注:这里需要声明使用H5模式的dialog,参考文档dialog

阻止关闭dialog

用户输入完成后,点击”确认“按钮,验证密码。

mui.confirm('<input type="password" id="test" />', 'Hello MUI', null, function(event) {  
    var index = event.index;  
    if(index === 1) {  
        var pwd = document.getElementById('test').value;  
        // 验证失败返回false  
        return false;  
    }  
},'div');  

修改按钮的默认行为后,在回调函数中返回false,则不会关闭dialog。

错误信息

在拼接密码输入框的同时,见错误信息提示的元素一起拼接。

mui.confirm('<input type="password" id="test" /><span id="error">&nbsp</span>', 'Hello MUI', null, function(event) {},'div');  

源码

附上源码,直接浏览即可。

收起阅读 »

流应用体验视频及入口说明

流应用

流应用有多种入口来源,并非单一的应用市场搜索。

1. 使用DCloud流应用管理器

手机访问http://m3w.cn,可下载DCloud流应用管理器,获取和管理本机流应用。

2. 360手机助手搜索秒开流应用

2015年10月起的360手机助手起,支持搜索流应用名字,显示秒开按钮。
http://v.qq.com/boke/gplay/c17d8789e7dd8a208cd6e6189ae90664_nst000001qufah3_i0171dyo7cf.html

3. 金立手机软件商店秒开流应用

2017年6月起的金立软件商店版本,可以在搜索页面下方推荐位及软件分类-即点即用里使用流应用。https://bbs.amigo.cn/forum.php?mod=viewthread&tid=217285
手机原厂支持的流应用,体验更优秀。

4. 360手机浏览器秒开流应用

2016年11月起,360手机浏览器8.0安卓版,开始内嵌流应用引擎。
在地址栏里敲vip.com,可以直接进入流应用。
使用时有3点注意:1.360浏览器会在WiFi下静默下载流应用插件,如果插件没下载完或不是在WiFi下,启动时仍然是普通H5。2. 普通H5和流应用的区别是,流应用顶部有一个黑色的导航条,没有地址栏。
https://v.qq.com/x/page/n0336208o73.html

5. 青柠桌面云文件夹

青柠桌面是国内较大的第三方laucher,其预置了流应用云文件夹,里面的应用即点即用又可以达到原生体验。实现了更高效率的分发变现。
可以点击这里下载体验

6. 快码,扫描立即秒装app

快码是一种集成了流应用、原生App下载、微信公众号关注、微博关注于一体的统一码。
快码是连接线上线下最便捷的方式。
http://v.qq.com/boke/gplay/c17d8789e7dd8a208cd6e6189ae90664_nst000001qufah3_w0171ems73j.html

快码还具备扫码直通功能,扫码如下的码,能直接进入到大众点评外卖里的必胜客餐厅。

打通App孤岛,直达内容,这是HTML5及流应用的重要优势。

7. 分享,通过社交网络快速传播app

分享一个App,就像分享一个消息。
http://v.qq.com/boke/gplay/c17d8789e7dd8a208cd6e6189ae90664_nst000001qufah3_r0171bswy6f.html

分享同样支持分享直通车,可以分享App里的具体内容, 比如:
一个资讯App的某条文章;
一个视频App的某个电影;
一个电商App的某个商品...

8. 推送流应用

推送是推广的大杀器,只要精准筛选目标用户,在合适的时间、给合适的人以合适的信息,点击推送后App立即安装激活。推广效率可以用“恐怖”来形容。
http://v.qq.com/boke/gplay/c17d8789e7dd8a208cd6e6189ae90664_nst000001qufah3_k0171y6vfyu_x01833hx4q3.html

9. 手机网页打开流应用

这里有文章专门讲解如何通过wap浏览器打开流应用,把wap用户变成app用户。http://ask.dcloud.net.cn/article/579
视频如下:http://v.qq.com/boke/gplay/c17d8789e7dd8a208cd6e6189ae90664_nst000001qufah3_k0171y6vfyu_t0190xh3198.html

10. 从一个App里打开流应用

app互推荐或应用内广告,也是流应用的流量来源。因为原生app的下载安装麻烦,所以一直以来积分墙等app互推业务并没有起量。但app向流应用导流的效果要好于向原生app数倍,重新打开了这个流量市场。
文档:http://ask.dcloud.net.cn/article/670

11. 清理卸载入口

360手机助手从2016年7月起的版本,在清理应用卸载时,会提示用户是否在桌面放一个微应用快捷方式图标在桌面。


每天有数千万人在清理卸载原生App。
非Top30的App,如果体积大、有后台耗电,很容易被用户清理掉。
原生Apk辛苦发展来的激活用户就此流失。
但有30%的用户在卸载后会点击保留微应用版本,实现低频应用的驻留。

继续阅读 »

流应用有多种入口来源,并非单一的应用市场搜索。

1. 使用DCloud流应用管理器

手机访问http://m3w.cn,可下载DCloud流应用管理器,获取和管理本机流应用。

2. 360手机助手搜索秒开流应用

2015年10月起的360手机助手起,支持搜索流应用名字,显示秒开按钮。
http://v.qq.com/boke/gplay/c17d8789e7dd8a208cd6e6189ae90664_nst000001qufah3_i0171dyo7cf.html

3. 金立手机软件商店秒开流应用

2017年6月起的金立软件商店版本,可以在搜索页面下方推荐位及软件分类-即点即用里使用流应用。https://bbs.amigo.cn/forum.php?mod=viewthread&tid=217285
手机原厂支持的流应用,体验更优秀。

4. 360手机浏览器秒开流应用

2016年11月起,360手机浏览器8.0安卓版,开始内嵌流应用引擎。
在地址栏里敲vip.com,可以直接进入流应用。
使用时有3点注意:1.360浏览器会在WiFi下静默下载流应用插件,如果插件没下载完或不是在WiFi下,启动时仍然是普通H5。2. 普通H5和流应用的区别是,流应用顶部有一个黑色的导航条,没有地址栏。
https://v.qq.com/x/page/n0336208o73.html

5. 青柠桌面云文件夹

青柠桌面是国内较大的第三方laucher,其预置了流应用云文件夹,里面的应用即点即用又可以达到原生体验。实现了更高效率的分发变现。
可以点击这里下载体验

6. 快码,扫描立即秒装app

快码是一种集成了流应用、原生App下载、微信公众号关注、微博关注于一体的统一码。
快码是连接线上线下最便捷的方式。
http://v.qq.com/boke/gplay/c17d8789e7dd8a208cd6e6189ae90664_nst000001qufah3_w0171ems73j.html

快码还具备扫码直通功能,扫码如下的码,能直接进入到大众点评外卖里的必胜客餐厅。

打通App孤岛,直达内容,这是HTML5及流应用的重要优势。

7. 分享,通过社交网络快速传播app

分享一个App,就像分享一个消息。
http://v.qq.com/boke/gplay/c17d8789e7dd8a208cd6e6189ae90664_nst000001qufah3_r0171bswy6f.html

分享同样支持分享直通车,可以分享App里的具体内容, 比如:
一个资讯App的某条文章;
一个视频App的某个电影;
一个电商App的某个商品...

8. 推送流应用

推送是推广的大杀器,只要精准筛选目标用户,在合适的时间、给合适的人以合适的信息,点击推送后App立即安装激活。推广效率可以用“恐怖”来形容。
http://v.qq.com/boke/gplay/c17d8789e7dd8a208cd6e6189ae90664_nst000001qufah3_k0171y6vfyu_x01833hx4q3.html

9. 手机网页打开流应用

这里有文章专门讲解如何通过wap浏览器打开流应用,把wap用户变成app用户。http://ask.dcloud.net.cn/article/579
视频如下:http://v.qq.com/boke/gplay/c17d8789e7dd8a208cd6e6189ae90664_nst000001qufah3_k0171y6vfyu_t0190xh3198.html

10. 从一个App里打开流应用

app互推荐或应用内广告,也是流应用的流量来源。因为原生app的下载安装麻烦,所以一直以来积分墙等app互推业务并没有起量。但app向流应用导流的效果要好于向原生app数倍,重新打开了这个流量市场。
文档:http://ask.dcloud.net.cn/article/670

11. 清理卸载入口

360手机助手从2016年7月起的版本,在清理应用卸载时,会提示用户是否在桌面放一个微应用快捷方式图标在桌面。


每天有数千万人在清理卸载原生App。
非Top30的App,如果体积大、有后台耗电,很容易被用户清理掉。
原生Apk辛苦发展来的激活用户就此流失。
但有30%的用户在卸载后会点击保留微应用版本,实现低频应用的驻留。

收起阅读 »

Deferred long-running timer task(s)...

Deferred long-running timer task(s) to improve scrolling smoothness. See crbug.com/574343

Deferred long-running timer task(s) to improve scrolling smoothness. See crbug.com/574343

Mui前端架子(编程规范分享)

mui

原文标题:PHP Lumen - 入门教程 - web前端架子
转来自我的博客:http://blog.csdn.net/wowkk/article/details/52254696

用了Lumen一段时间了,感觉还不错。也适合全栈开发。因为我一丢丢PHP基础都没看就直接用起了框架,挺多地方还是闹笑话了。比如,字符串追加,PHP它喵的居然是用 “.” 来追加,而通过“->”进行属性调用也是不爽~

这个web前端架子,不是Lumen专用的,额外分享。

首先我写了一个公共类(common.js),主要用来进行封装请求的。

/*!  
 * =====================================================  
 * 全局通用变量  
 * =====================================================  
 */  
var Common = {};  
//Common.ServerUrl = "http://120.24.xx.xx:8080/";       //线上测试版本  
Common.ServerUrl = "http://192.168.0.110:8080/";    //公司测试版本  
//Common.ServerUrl = "http://192.168.99.139:8080/";     //宿舍测试版本  

Common.Post = function(url,data,successcallback,errcallback){  
    console.log(Common.jsonToUrl(url,data));  
    if(errcallback==null){  
        errcallback = function(xhr,type,errorThrown){  
            console.log(JSON.stringify(xhr))  
            plus.nativeUI.closeWaiting();//关闭旋转菊花  
            alert("网络异常:" + url);  
        }  
    }  
    //这里的mui是HBuilder跨平台开发工具自己的js,根据自己项目调改。  
    mui.ajax(Common.ServerUrl + url,{  
        data:data,  
        dataType:'json',  
        type:'post',  
        timeout:5000,  
        success:successcallback,  
        error:errcallback  
    });  
}  

Common.jsonToUrl=function(url,jsonData){  
    var full_url = Common.ServerUrl + url + "?";  
    for(var index in jsonData){  
        full_url = full_url + index + "=" + jsonData[index] + "&";  
    }  
    return full_url;  
};

可以把这段代码塞到js插件里面去(比如jQuery)减少请求。
这一丢丢代码有几个好处:
1.统一请求的url,不需要每个页面都去设置请求地址。页面发送ajax时,只需要把相对路径传进来就行了。
2.统一错误返回的处理,可以即时知道哪个请求出错。也可以根据需要特殊回调处理。
3.把post的data转换为url地址,方便直接复制到浏览器进行get调试。
4.方便拓展与维护,比如可以统一处理“未登录则自动跳转到登录页”。

再看下html页的代码

<script>  
        /*  
         * 页面配置  
         */  
        var PAGE = {  
                View: {},  
                page: 0,  
                Model: {  
                    Article: function(article) {  
                        return '<article id="' + article.information_id + '">' +  
                            '<div class="article-time">' +  
                            '<span>' + article.time_title + '</span>' +  
                            '</div>' +  
                            '<div class="article-bg" style="background-image: url(' + article.information_imgurl + ');">' +  
                            '<div class="article-bg-cover">' +  
                            '<span class="information_title"># ' + article.information_title + '</span>' +  
                            '</div>' +  
                            '</div>' +  
                            '<div class="mui-pull-right article_collect">' +  
                            '<img style="width: 100%;" src="../../img/news_shoucang.png" />' +  
                            '<div class="article_collect_fone">' + article.favour_num + '</div>' +  
                            '</div>' +  
                            '</article>';  
                    },  
                    Articles:function(articles){  
                        var html = "";  
                        for(var i = 0; i < articles.length; i++) {  
                            html += PAGE.Model.Article(articles[i]);  
                        }  
                        return html;  
                    }  
                }  
            };  
        mui.init();//(mui框架需要)初始化框架  
        mui.plusReady(function() {  
            PAGE.Init();//初始化本页面  
        });  
        /*  
         * 页面初始化  
         */  
        PAGE.Init = function() {  
                PAGE.preloadView();  
                PAGE.addEventListener();  
            }  
            /*  
             * 页面预加载  
             */  
        PAGE.preloadView = function() {}  
            /*  
             * 事件监听  
             */  
        PAGE.addEventListener = function() {  
            PAGE.addEventListener_Article();//确定监听点击文章列表的元素  
        }  
            /*  
             * 页面预加载-实现  
             */  
        PAGE.preloadView_Name = function() {}  
            /*  
             * 事件监听-实现  
             */  
        PAGE.addEventListener_Article = function() {  
                mui("#div_newList").on("tap", "article", function() {  
                    mui.openWindow({  
                        id: "/View/News/details.html",  
                        url: "/View/News/details.html",  
                        extras: {  
                            information_id: this.id,  
                            information_title: this.getElementsByClassName("information_title")[0].innerText,  
                            information_imgurl: this.getElementsByClassName("article-bg")[0].style.backgroundImage  
                        }  
                    })  
                })  
            }  
            /*  
             * 事件实现  
             */  
        PAGE.Event_Name = function() {}  
    </script>

编出来的这段,个人用起来还是比较舒服的。
1.所有js代码都是在PAGE这个域里面,尽量避免污染。
2.将所有监听事件独个封装起来,然后由PAGE.addEventListener统一调用。这样在简单事件较多的情况下,代码也足够清晰易阅读和定位。
3.所有动态生成的代码放在PAGE.Model对象里面(传人json数据,返回对应的html代码)。同样也是清晰易阅读和定位。
4.普通函数比如,更新页面数据就用PAGE.Event_XXX格式命名函数。这个主要就是统一规范吧。
5.一些配置变量,比如当前页PageNum,也可以防止PAGE里面去维护。

接下来继续实战,看能不能怎么优化。现在为了性能,大多数都是用原生js,看看有没有机会封装个js架子。

继续阅读 »

原文标题:PHP Lumen - 入门教程 - web前端架子
转来自我的博客:http://blog.csdn.net/wowkk/article/details/52254696

用了Lumen一段时间了,感觉还不错。也适合全栈开发。因为我一丢丢PHP基础都没看就直接用起了框架,挺多地方还是闹笑话了。比如,字符串追加,PHP它喵的居然是用 “.” 来追加,而通过“->”进行属性调用也是不爽~

这个web前端架子,不是Lumen专用的,额外分享。

首先我写了一个公共类(common.js),主要用来进行封装请求的。

/*!  
 * =====================================================  
 * 全局通用变量  
 * =====================================================  
 */  
var Common = {};  
//Common.ServerUrl = "http://120.24.xx.xx:8080/";       //线上测试版本  
Common.ServerUrl = "http://192.168.0.110:8080/";    //公司测试版本  
//Common.ServerUrl = "http://192.168.99.139:8080/";     //宿舍测试版本  

Common.Post = function(url,data,successcallback,errcallback){  
    console.log(Common.jsonToUrl(url,data));  
    if(errcallback==null){  
        errcallback = function(xhr,type,errorThrown){  
            console.log(JSON.stringify(xhr))  
            plus.nativeUI.closeWaiting();//关闭旋转菊花  
            alert("网络异常:" + url);  
        }  
    }  
    //这里的mui是HBuilder跨平台开发工具自己的js,根据自己项目调改。  
    mui.ajax(Common.ServerUrl + url,{  
        data:data,  
        dataType:'json',  
        type:'post',  
        timeout:5000,  
        success:successcallback,  
        error:errcallback  
    });  
}  

Common.jsonToUrl=function(url,jsonData){  
    var full_url = Common.ServerUrl + url + "?";  
    for(var index in jsonData){  
        full_url = full_url + index + "=" + jsonData[index] + "&";  
    }  
    return full_url;  
};

可以把这段代码塞到js插件里面去(比如jQuery)减少请求。
这一丢丢代码有几个好处:
1.统一请求的url,不需要每个页面都去设置请求地址。页面发送ajax时,只需要把相对路径传进来就行了。
2.统一错误返回的处理,可以即时知道哪个请求出错。也可以根据需要特殊回调处理。
3.把post的data转换为url地址,方便直接复制到浏览器进行get调试。
4.方便拓展与维护,比如可以统一处理“未登录则自动跳转到登录页”。

再看下html页的代码

<script>  
        /*  
         * 页面配置  
         */  
        var PAGE = {  
                View: {},  
                page: 0,  
                Model: {  
                    Article: function(article) {  
                        return '<article id="' + article.information_id + '">' +  
                            '<div class="article-time">' +  
                            '<span>' + article.time_title + '</span>' +  
                            '</div>' +  
                            '<div class="article-bg" style="background-image: url(' + article.information_imgurl + ');">' +  
                            '<div class="article-bg-cover">' +  
                            '<span class="information_title"># ' + article.information_title + '</span>' +  
                            '</div>' +  
                            '</div>' +  
                            '<div class="mui-pull-right article_collect">' +  
                            '<img style="width: 100%;" src="../../img/news_shoucang.png" />' +  
                            '<div class="article_collect_fone">' + article.favour_num + '</div>' +  
                            '</div>' +  
                            '</article>';  
                    },  
                    Articles:function(articles){  
                        var html = "";  
                        for(var i = 0; i < articles.length; i++) {  
                            html += PAGE.Model.Article(articles[i]);  
                        }  
                        return html;  
                    }  
                }  
            };  
        mui.init();//(mui框架需要)初始化框架  
        mui.plusReady(function() {  
            PAGE.Init();//初始化本页面  
        });  
        /*  
         * 页面初始化  
         */  
        PAGE.Init = function() {  
                PAGE.preloadView();  
                PAGE.addEventListener();  
            }  
            /*  
             * 页面预加载  
             */  
        PAGE.preloadView = function() {}  
            /*  
             * 事件监听  
             */  
        PAGE.addEventListener = function() {  
            PAGE.addEventListener_Article();//确定监听点击文章列表的元素  
        }  
            /*  
             * 页面预加载-实现  
             */  
        PAGE.preloadView_Name = function() {}  
            /*  
             * 事件监听-实现  
             */  
        PAGE.addEventListener_Article = function() {  
                mui("#div_newList").on("tap", "article", function() {  
                    mui.openWindow({  
                        id: "/View/News/details.html",  
                        url: "/View/News/details.html",  
                        extras: {  
                            information_id: this.id,  
                            information_title: this.getElementsByClassName("information_title")[0].innerText,  
                            information_imgurl: this.getElementsByClassName("article-bg")[0].style.backgroundImage  
                        }  
                    })  
                })  
            }  
            /*  
             * 事件实现  
             */  
        PAGE.Event_Name = function() {}  
    </script>

编出来的这段,个人用起来还是比较舒服的。
1.所有js代码都是在PAGE这个域里面,尽量避免污染。
2.将所有监听事件独个封装起来,然后由PAGE.addEventListener统一调用。这样在简单事件较多的情况下,代码也足够清晰易阅读和定位。
3.所有动态生成的代码放在PAGE.Model对象里面(传人json数据,返回对应的html代码)。同样也是清晰易阅读和定位。
4.普通函数比如,更新页面数据就用PAGE.Event_XXX格式命名函数。这个主要就是统一规范吧。
5.一些配置变量,比如当前页PageNum,也可以防止PAGE里面去维护。

接下来继续实战,看能不能怎么优化。现在为了性能,大多数都是用原生js,看看有没有机会封装个js架子。

收起阅读 »

底部选项卡被输入法撑起问题解决

输入法 选项卡

1.如果是单页面出现的问题,可以使用
mui.plusReady(function() {
//设置bottom绝对位置
document.getElementById('bottomx').style.top = (plus.display.resolutionHeight - 50) + "px";
});
这段代码 转自:解决弹出输入法时页面高度变小导致底部上浮的问题

2.如果选项卡在父页面中,并且在页面中的样式中设置了bottom属性,可以使用
mui.plusReady(function(){
var self=plus.webview.currentWebview();
/**

  • 防止 在write页面输入文字的时候 , 输入法把选项卡撑起来
    */
    var parentVebView =self.opener();
    //防止 父页面选项卡被输入法撑起
    window.addEventListener('resize', function() {
    var a=plus.android.invoke(plus.android.currentWebview(),"getHeight") ;
    var b=plus.navigator.getStatusbarHeight();
    var c=plus.screen.resolutionHeight ;
    var d=(c-a-b);
    console.info('webview高度:'+a+" 状态栏高度:"+b+" 屏幕高度:"+c+" 输入法高度:"+d)
    d >0 ? self.setStyle({top: '45px',bottom: '0px'}) : self.setStyle({top: '45px',bottom: '50px'});
    //d > 0 ? parentVebView.evalJS("mui('#nav_id').css('position','absolute');") : parentVebView.evalJS("mui('#nav_id').css('position','fixed');");
    }, false);
    });
    当输入法打开时 重新设置当前webview的 style属性
继续阅读 »

1.如果是单页面出现的问题,可以使用
mui.plusReady(function() {
//设置bottom绝对位置
document.getElementById('bottomx').style.top = (plus.display.resolutionHeight - 50) + "px";
});
这段代码 转自:解决弹出输入法时页面高度变小导致底部上浮的问题

2.如果选项卡在父页面中,并且在页面中的样式中设置了bottom属性,可以使用
mui.plusReady(function(){
var self=plus.webview.currentWebview();
/**

  • 防止 在write页面输入文字的时候 , 输入法把选项卡撑起来
    */
    var parentVebView =self.opener();
    //防止 父页面选项卡被输入法撑起
    window.addEventListener('resize', function() {
    var a=plus.android.invoke(plus.android.currentWebview(),"getHeight") ;
    var b=plus.navigator.getStatusbarHeight();
    var c=plus.screen.resolutionHeight ;
    var d=(c-a-b);
    console.info('webview高度:'+a+" 状态栏高度:"+b+" 屏幕高度:"+c+" 输入法高度:"+d)
    d >0 ? self.setStyle({top: '45px',bottom: '0px'}) : self.setStyle({top: '45px',bottom: '50px'});
    //d > 0 ? parentVebView.evalJS("mui('#nav_id').css('position','absolute');") : parentVebView.evalJS("mui('#nav_id').css('position','fixed');");
    }, false);
    });
    当输入法打开时 重新设置当前webview的 style属性
收起阅读 »

mui主动触发上拉下拉加载

mui.init({
pullRefresh : {
container:refreshContainer,//待刷新区域标识,querySelector能定位的css选择器均可,比如:id、.class等
up : {
contentrefresh : "正在加载...",//可选,正在加载状态时,上拉加载控件上显示的标题内容
contentnomore:'没有更多数据了',//可选,请求完毕若没有更多数据时显示的提醒内容;
callback :pullfresh-function ,
auto:true//页面加载完就加载一次
}
}
});

主动下拉加载
mui('#pullrefresh').pullRefresh().pulldownLoading();
主动上拉加载
mui('#pullrefresh').pullRefresh().pullupLoading();

继续阅读 »

mui.init({
pullRefresh : {
container:refreshContainer,//待刷新区域标识,querySelector能定位的css选择器均可,比如:id、.class等
up : {
contentrefresh : "正在加载...",//可选,正在加载状态时,上拉加载控件上显示的标题内容
contentnomore:'没有更多数据了',//可选,请求完毕若没有更多数据时显示的提醒内容;
callback :pullfresh-function ,
auto:true//页面加载完就加载一次
}
}
});

主动下拉加载
mui('#pullrefresh').pullRefresh().pulldownLoading();
主动上拉加载
mui('#pullrefresh').pullRefresh().pullupLoading();

收起阅读 »

怎么从零开始学习Dcloud的技术,开发手机APP?

5+App开发 mui HBuilder 视频教程 学习

推荐国内首推的跨平台移动APP开发专业培训机构-东翌学院是Dcloud的合作培训机构,跨平台APP开发整体课程在线直播+课程源码+全套视频,最新最全的APP开发,HB和MUI的全套视频,零基础都可以学习,更有高级进修课程,30天最快速的开发跨平台APP!咨询报名QQ:410355878 网址:http://www.dongyixueyuan.com/ 欢迎有意向学习的朋友加好友咨询!谢谢Dcloud提供这么好的平台!

立即学习

继续阅读 »

推荐国内首推的跨平台移动APP开发专业培训机构-东翌学院是Dcloud的合作培训机构,跨平台APP开发整体课程在线直播+课程源码+全套视频,最新最全的APP开发,HB和MUI的全套视频,零基础都可以学习,更有高级进修课程,30天最快速的开发跨平台APP!咨询报名QQ:410355878 网址:http://www.dongyixueyuan.com/ 欢迎有意向学习的朋友加好友咨询!谢谢Dcloud提供这么好的平台!

立即学习

收起阅读 »