HBuilderX

HBuilderX

极客开发工具
uni-app

uni-app

开发一次,多端覆盖
uniCloud

uniCloud

云开发平台
HTML5+

HTML5+

增强HTML5的功能体验
MUI

MUI

上万Star的前端框架

HBuilder+MUI开发APP实战-司机签收系统(二)Common.js封装

mui HBuilder

这部分直接上代码,都是自己一行一行码出来的,每个方法都非常有用:

  • msg: function(msg, icon, timer) 弹出层
  • alert: function(msg, icon, callback) 弹出框,带确认按钮,可事件回调
  • confrim: function(msg, callback) 确认框,带事件回调
  • open: function(url, params, aniShow) 打开新页面,or 页面跳转
  • close: function() 关闭当前页面
  • exit: function() Android下直接退出,ios不支持
  • backExit: function() 点击2次返回退出app
  • currPageId: function(callback) 获取当前窗体的ID
  • getParam: function(key, callback) 获取上个页面船体过来的参数
  • GetUrlParms: function() 获取get url地址里的所有参数,返回数组
  • isBrowser:这是个属性,用来判定是否是在浏览器中打开,如果一套代码想兼容app和微信,这个很有用
  • loading: function() 自定义的弹出loading,加载数据前显示
  • loadingClose: function(timer) 关闭loading
  • ajax: function(type, url, params, callback, callbackErr, el) 异步请求数据,支持post、get、put、delete等。
  • update: function() 系统自动升级
  • updateCheck: function() 自动升级的具体实现
  • validaCom:验证规则封装
  • jsonCom:操作JSON封装
  • dataCom 数据存储封装
  • netCom:网络监测封装
  • account:当前登录用户信息封装

    define(['_', 'layer', 'config', 'common'], function(_, layer, config) {  
    return {  
        //系统提醒  
        msg: function(msg, icon, timer) {  
            timer = (timer == undefined ? 1500 : timer*1000);  
            layer.msg(msg, {  
                icon: icon,  
                anim: 0,  
                time: timer  
            });  
        },  
        //系统弹出提醒  
        alert: function(msg, icon, callback) {  
            layer.msg(msg, {  
                title: '',  
                icon: icon,  
                shade: 0.3,  
                shadeClose: false,  
                btnAlign: 'c',  
                btn: ['我知道了'],  
                time: 9999999,  
                yes: function(idx) {  
                    if(callback)  
                        callback();  
                    layer.close(idx);  
                }  
            });  
        },  
        confrim: function(msg, callback) {  
            var my = this;  
            layer.msg(msg, {  
                time: 9999999,  
                icon: 3,  
                shade: 0.3,  
                shadeClose: false,  
                btn: ['确 定', '取 消'],  
                yes: function(index) {  
                    if(callback)  
                        callback();  
                    layer.close(index);  
                }  
    
            });  
        },  
        //打开新窗体  
        open: function(url, params, aniShow) {  
            var my = this;  
            if(!my.isBrowser) { //app跳转  
                if(!aniShow) {  
                    var anType = ['slide-in-right', 'slide-in-left', 'slide-in-top', 'slide-in-bottom', 'fade-in', 'zoom-out', 'zoom-fade-out', 'pop-in'];  
                    var anIdx = Math.floor((Math.random() * anType.length));  
                    if(mui.os.ios)  
                        aniShow = anType[anType.length - 1];  
                    else  
                        aniShow = anType[0];  
    
                }  
                mui.openWindow({  
                    id: url,  
                    url: url,  
                    extras: params,  
                    createNew: false,  
                    show: {  
                        autoShow: true, //页面loaded事件发生后自动显示,默认为true  
                        aniShow: aniShow, //anType[anIdx], //页面显示动画,默认为”slide-in-right“;  
                        duration: 200 //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒;  
                    },  
                    waiting: {  
                        autoShow: false, //自动显示等待框,默认为true  
                        title: config.dictionary.strings.LOADING, //等待对话框上显示的提示内容  
                        options: {  
                            //back:'none',  
                            background: 'rgba(0,0,0,0.75)',  
                            round: 5,  
                            loading: {  
                                //icon: '/img/loading-png.png',  
                                height: '50px',  
                                display: 'inline'  
                            }  
                        }  
                    },  
                })  
            } else { //浏览器跳转  
                var newUrl = url;  
                var newParams;  
                if(params != null) {  
                    newParams = my.jsonCom.jsonToUrlParam(params);  
                    url += "?" + newParams;  
                }  
                //加随机参数清缓存  
                if(url.indexOf('?') == -1)  
                    url += '?_=' + (new Date().getTime());  
                else  
                    url += '&_=' + (new Date().getTime());  
                top.location.href = url;  
            }  
        },  
        //关闭窗体  
        close: function() {  
            if(!this.isBrowser) {  
                var ws = plus.webview.currentWebview();  
                plus.webview.close(ws);  
            } else  
                history.back();  
        },  
        exit: function() {  
            plus.runtime.quit();  
        },  
        //双击返回退出APP  
        backExit: function() {  
            var my = this;  
            if(!my.isBrowser) {  
                var _clickNum = 0;  
                mui.init({  
                    beforeback: function() {  
                        _clickNum++;  
                        if(_clickNum > 1) {  
                            plus.runtime.quit();  
                        } else {  
                            my.msg("再按一次退出应用");  
                        }  
                        setTimeout(function() {  
                            _clickNum = 0;  
                        }, 1000);  
                        return false;  
                    }  
                });  
            }  
        },  
        //获取当前页面ID  
        currPageId: function(callback) {  
            if(sysCom.isBrowser)  
                callback(location.href);  
            else {  
                mui.plusReady(function() {  
                    callback(plus.webview.getLaunchWebview().getURL());  
                });  
            }  
        },  
        //获取页面参数  
        getParam: function(key, callback) {  
            if(!sysCom.isBrowser) {  
                mui.plusReady(function() {  
                    var wv = plus.webview.currentWebview();  
                    var value = wv[key];  
                    callback(value);  
                });  
            } else {  
                var value = urlCom.getParam(key);  
                callback(value);  
            }  
        },  
        //获取URL所有参数  
        GetUrlParms: function() {  
            var args = new Object();  
            var query = location.search.substring(1); //获取查询串  
            var pairs = query.split("&"); //在逗号处断开  
            for(var i = 0; i < pairs.length; i++) {  
                var pos = pairs[i].indexOf('='); //查找name=value  
                if(pos == -1) continue; //如果没有找到就跳过  
                var argname = pairs[i].substring(0, pos); //提取name  
                var value = pairs[i].substring(pos + 1); //提取value  
                args[argname] = decodeURIComponent(value); //存为属性  
            }  
            return args;  
        },  
        //是否是普通浏览器打开  
        isBrowser: !mui.os.plus,  
        //loading弹出层  
        loading: function() {  
            var box = $('#loading-layout');  
            if(box.length == 0) {  
                $('body').append('<div id="loading-layout"><div class="loading"></div></div>');  
                box = $('#loading-layout');  
            }  
            var box_loading = $('#loading-layout .loading');  
            var width = box.width();  
            var height = box.height();  
            var width_loading = box_loading.width();  
            var height_loading = box_loading.height();  
            $('#loading-layout .loading').css('top', (height - height_loading) / 2 + 'px')  
            $('#loading-layout .loading').css('left', (width - width_loading) / 2 + 'px')  
            box.show();  
        },  
        //关闭弹出层  
        loadingClose: function(timer) {  
            setTimeout(function() {  
                $('#loading-layout').remove();  
            }, (timer ? timer : 0))  
        },  
        /******* http 请求 *******/  
        //请求 get  
        ajax: function(type, url, params, callback, callbackErr, el) {  
            var my = this;  
            if(!config.appCONFIG.netStatus) {  
                my.msg(config.dictionary.strings.NO_NET_POST)  
                if(callbackErr)  
                    callbackErr(config.dictionary.strings.NO_NET_POST);  
                return false;  
            }  
            var el_txt = '';  
            var timer;  
            var timer_sec = 0;  
            if(el) {  
                el_txt = $(el).text();  
                $(el).attr('disabled', true).text('正在提交');  
                timer = setInterval(function() {  
                    if(timer_sec < 3) {  
                        $(el).text($(el).text() + '.');  
                        timer_sec++;  
                    } else {  
                        $(el).text('正在提交');  
                        timer_sec = 0;  
                    }  
                }, 500);  
            }  
            //my.loading();  
            $.ajax({  
                url: url,  
                type: type, //GET  
                async: true, //或false,是否异步  
                data: params,  
                timeout: 15000, //超时时间  
                dataType: 'jsonp',  
                jsonp: "theFunction",  
                success: function(data, textStatus, jqXHR) {  
                    callback(data);  
                },  
                error: function(xhr, textStatus) {  
                    if(textStatus == "error")  
                        my.msg(config.dictionary.strings.SERVER_ERROR);  
                    else if(textStatus == "timeout")  
                        my.msg(config.dictionary.strings.TIMEOUT);  
                    else {  
                        //console.log(xhr.responseText)  
                        var jsonXhr = JSON.parse(xhr.responseText);  
                        //令牌错误重新登陆  
                        if(jsonXhr.ExceptionMessage == config.dictionary.strings.INVALID_TOKEN) {  
                            my.msg(config.dictionary.strings.INVALID_TOKEN_ERR);  
                        } else {  
                            my.msg("error:" + jsonXhr.ExceptionMessage);  
                        }  
                    }  
                    if(callbackErr)  
                        callbackErr(xhr, textStatus);  
                },  
                complete: function() {  
                    //my.loadingClose();  
                    if(el) {  
                        $(el).text(el_txt)  
                        $(el).removeAttr('disabled');  
                        clearInterval(timer);  
                    }  
                }  
            })  
        },  
        //系统自动更新  
        update: function() {  
            if(window.plus) {  
                this.updateCheck();  
            } else {  
                document.addEventListener('plusready', this.updateCheck, false);  
            }  
        },  
        //系统升级检测  
        updateCheck: function() {  
            var appVer = ''; //app版本  
            var newVer = ''; //最新版本  
            //获得当前版本  
            plus.runtime.getProperty(plus.runtime.appid, function(inf) {  
                appVer = inf.version;  
                $('.copyright').html('陕西中电新盛物流有限公司v' + appVer);  
                //console.log(1)  
                //发起新版本请求检测  
                var update_url = config.urlCONFIG.get_appupdate + "/version.txt?bust=" + (new Date().getTime());  
                //console.log(update_url)  
                $.get(update_url, {}, function(res) {  
                    var data = JSON.parse(res);  
                    newVer = data.version;  
                    fileType = 'wgt';  
                    if(appVer != newVer && parseInt(appVer.replaceAll('\\.', '')) < parseInt(newVer.replaceAll('\\.', ''))) {  
                        var waiting = plus.nativeUI.showWaiting("有新版本啦,正在下载更新 0%...", {  
                            width: '100%',  
                            height: '100%',  
                            //back: 'none',  
                            round: 1,  
                        });  
    
                        //下载更新包                   
                        var file_downing = plus.downloader.createDownload(config.urlCONFIG.get_appupdate + "/wgt/" + newVer + "." + fileType + "?_=" + (new Date().getTime()), {  
                            filename: "_doc/update/"  
                        }, function(d, status) {  
                            if(status == 200) {  
                                var _filename = d.filename;  
                                // 安装更新包  
                                plus.runtime.install(_filename, {}, function() {  
                                    //更新完毕删除更新包  
                                    plus.io.resolveLocalFileSystemURL(_filename, function(entity) {  
                                        entity.remove();  
                                    }, function(error) {  
                                        debugCom.log(error.message);  
                                    });  
                                    //如果是安卓自动重启应用,ios需要手动重启应用  
                                    if(mui.os.android) {  
                                        waiting.setTitle('更新完成,正在重新打开应用...');  
                                        setTimeout(function() {  
                                            plus.nativeUI.closeWaiting();  
                                            plus.runtime.restart();  
                                        }, 1000)  
                                    } else {  
                                        plus.nativeUI.closeWaiting();  
                                        mui.alert('更新完成,请彻底结束应用并重新打开!', '', function() {  
                                            //plus.runtime.restart();  
                                        })  
                                    }  
    
                                }, function(e) {  
                                    waiting.setTitle('更新失败:' + e.message);  
                                    setTimeout(function() {  
                                        plus.nativeUI.closeWaiting();  
                                    }, 2000);  
                                });  
                            } else {  
                                mui.toast('下载更新包出现问题:' + status)  
                            }  
                        });  
                        //下载百分比  
                        file_downing.addEventListener("statechanged", function() {  
                            var per = parseInt(file_downing.downloadedSize / file_downing.totalSize * 100);  
                            per = (per == NaN ? 0 : per);  
                            waiting.setTitle("有新版本啦,正在下载更新 " + per + "%");  
                        }, false);  
                        //开始下载  
                        file_downing.start();  
                    }  
    
                });  
            })  
        },  
        /********验证********/  
        validaCom: {  
            //验证正则  
            _regex: {  
                mobile: /^1+\d{10}$/,  
                isIDCard: /^\d{17}[\d|X|x]$|^\d{15}$/,  
                email: /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((.[a-zA-Z0-9_-]{2,3}){1,2})$/,  
            },  
            //验证手机  
            isMobile: function(txt) {  
                return this._regex.mobile.test(txt);  
            },  
            //验证邮箱  
            isEmail: function(txt) {  
                return this._regex.email.test(txt);  
            },  
            //身份证验证  
            isIDCard: function(txt) {  
                return this._regex.isIDCard.test(txt);  
            },  
        },  
        /********json操作********/  
        jsonCom: {  
            //将json转成url参数  
            jsonToUrlParam: function(param, key) {  
                var my = this;  
                var paramStr = "";  
                if(param instanceof String || param instanceof Number || param instanceof Boolean) {  
                    paramStr += "&" + key + "=" + encodeURIComponent(param);  
                } else {  
                    $.each(param, function(i) {  
                        var k = key == null ? i : key + (param instanceof Array ? "[" + i + "]" : "." + i);  
                        paramStr += '&' + my.jsonToUrlParam(this, k);  
                    });  
                }  
                return paramStr.substr(1);  
            },  
            //将url参数转成json  
            urlParamToJson: function(url) {  
                if(url.indexOf("?") > -1) {  
                    var string_a = url.split('?')[1];  
                    if(string_a.length > 0) {  
                        var string = string_a.split('&');  
                        var res = {};  
                        for(var i = 0; i < string.length; i++) {  
                            var str = string[i].split('=');  
                            res[str[0]] = str[1];  
                        }  
                        return res;  
                    } else  
                        return null;  
                } else  
                    return null;  
    
            }  
        },  
        /********数据存储********/  
        dataCom: {  
            set: function(key, data) {  
                localStorage.setItem(key, data);  
            },  
            get: function(key) {  
                return localStorage.getItem(key);  
            },  
            remove: function(key) {  
                localStorage.removeItem(key)  
            },  
            clear: function() {  
                localStorage.clear();  
            }  
        },  
        /*********** 网络监测 *************/  
        netCom: {  
            init: function() {  
                var my = this;  
                //网络检测  
                mui.plusReady(function() {  
                    if(plus.networkinfo.getCurrentType() == plus.networkinfo.CONNECTION_NONE) {  
                        config.netStatus = false;  
                        layer.msg(config.dictionary.strings.NO_NET);  
                    }  
                    document.addEventListener("netchange", my.change, false);  
                });  
            },  
            change: function() {  
                var my = this;  
                mui.plusReady(function() {  
                    //获取当前网络类型  
                    var nt = plus.networkinfo.getCurrentType();  
                    switch(nt) {  
                        case plus.networkinfo.CONNECTION_ETHERNET:  
    
                        case plus.networkinfo.CONNECTION_WIFI:  
    
                        case plus.networkinfo.CONNECTION_CELL2G:  
    
                        case plus.networkinfo.CONNECTION_CELL3G:  
    
                        case plus.networkinfo.CONNECTION_CELL4G:  
                            if(!config.netStatus) {  
                                layer.msg(config.dictionary.strings.YES_NET);  
                            }  
                            config.netStatus = true;  
                            break;  
                        default:  
                            if(config.netStatus) {  
                                layer.msg(config.dictionary.strings.NO_NET);  
                            }  
                            config.netStatus = false;  
                            break;  
                    }  
                });  
            }  
        },  
        /*********** 用户信息 *************/  
        account: {  
            getUser: function() {  
                var datauser = localStorage.getItem('datauser');  
                if(datauser) {  
                    return JSON.parse(datauser);  
                } else {  
                    return null;  
                }  
            }  
        }  
    }  
    });
继续阅读 »

这部分直接上代码,都是自己一行一行码出来的,每个方法都非常有用:

  • msg: function(msg, icon, timer) 弹出层
  • alert: function(msg, icon, callback) 弹出框,带确认按钮,可事件回调
  • confrim: function(msg, callback) 确认框,带事件回调
  • open: function(url, params, aniShow) 打开新页面,or 页面跳转
  • close: function() 关闭当前页面
  • exit: function() Android下直接退出,ios不支持
  • backExit: function() 点击2次返回退出app
  • currPageId: function(callback) 获取当前窗体的ID
  • getParam: function(key, callback) 获取上个页面船体过来的参数
  • GetUrlParms: function() 获取get url地址里的所有参数,返回数组
  • isBrowser:这是个属性,用来判定是否是在浏览器中打开,如果一套代码想兼容app和微信,这个很有用
  • loading: function() 自定义的弹出loading,加载数据前显示
  • loadingClose: function(timer) 关闭loading
  • ajax: function(type, url, params, callback, callbackErr, el) 异步请求数据,支持post、get、put、delete等。
  • update: function() 系统自动升级
  • updateCheck: function() 自动升级的具体实现
  • validaCom:验证规则封装
  • jsonCom:操作JSON封装
  • dataCom 数据存储封装
  • netCom:网络监测封装
  • account:当前登录用户信息封装

    define(['_', 'layer', 'config', 'common'], function(_, layer, config) {  
    return {  
        //系统提醒  
        msg: function(msg, icon, timer) {  
            timer = (timer == undefined ? 1500 : timer*1000);  
            layer.msg(msg, {  
                icon: icon,  
                anim: 0,  
                time: timer  
            });  
        },  
        //系统弹出提醒  
        alert: function(msg, icon, callback) {  
            layer.msg(msg, {  
                title: '',  
                icon: icon,  
                shade: 0.3,  
                shadeClose: false,  
                btnAlign: 'c',  
                btn: ['我知道了'],  
                time: 9999999,  
                yes: function(idx) {  
                    if(callback)  
                        callback();  
                    layer.close(idx);  
                }  
            });  
        },  
        confrim: function(msg, callback) {  
            var my = this;  
            layer.msg(msg, {  
                time: 9999999,  
                icon: 3,  
                shade: 0.3,  
                shadeClose: false,  
                btn: ['确 定', '取 消'],  
                yes: function(index) {  
                    if(callback)  
                        callback();  
                    layer.close(index);  
                }  
    
            });  
        },  
        //打开新窗体  
        open: function(url, params, aniShow) {  
            var my = this;  
            if(!my.isBrowser) { //app跳转  
                if(!aniShow) {  
                    var anType = ['slide-in-right', 'slide-in-left', 'slide-in-top', 'slide-in-bottom', 'fade-in', 'zoom-out', 'zoom-fade-out', 'pop-in'];  
                    var anIdx = Math.floor((Math.random() * anType.length));  
                    if(mui.os.ios)  
                        aniShow = anType[anType.length - 1];  
                    else  
                        aniShow = anType[0];  
    
                }  
                mui.openWindow({  
                    id: url,  
                    url: url,  
                    extras: params,  
                    createNew: false,  
                    show: {  
                        autoShow: true, //页面loaded事件发生后自动显示,默认为true  
                        aniShow: aniShow, //anType[anIdx], //页面显示动画,默认为”slide-in-right“;  
                        duration: 200 //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒;  
                    },  
                    waiting: {  
                        autoShow: false, //自动显示等待框,默认为true  
                        title: config.dictionary.strings.LOADING, //等待对话框上显示的提示内容  
                        options: {  
                            //back:'none',  
                            background: 'rgba(0,0,0,0.75)',  
                            round: 5,  
                            loading: {  
                                //icon: '/img/loading-png.png',  
                                height: '50px',  
                                display: 'inline'  
                            }  
                        }  
                    },  
                })  
            } else { //浏览器跳转  
                var newUrl = url;  
                var newParams;  
                if(params != null) {  
                    newParams = my.jsonCom.jsonToUrlParam(params);  
                    url += "?" + newParams;  
                }  
                //加随机参数清缓存  
                if(url.indexOf('?') == -1)  
                    url += '?_=' + (new Date().getTime());  
                else  
                    url += '&_=' + (new Date().getTime());  
                top.location.href = url;  
            }  
        },  
        //关闭窗体  
        close: function() {  
            if(!this.isBrowser) {  
                var ws = plus.webview.currentWebview();  
                plus.webview.close(ws);  
            } else  
                history.back();  
        },  
        exit: function() {  
            plus.runtime.quit();  
        },  
        //双击返回退出APP  
        backExit: function() {  
            var my = this;  
            if(!my.isBrowser) {  
                var _clickNum = 0;  
                mui.init({  
                    beforeback: function() {  
                        _clickNum++;  
                        if(_clickNum > 1) {  
                            plus.runtime.quit();  
                        } else {  
                            my.msg("再按一次退出应用");  
                        }  
                        setTimeout(function() {  
                            _clickNum = 0;  
                        }, 1000);  
                        return false;  
                    }  
                });  
            }  
        },  
        //获取当前页面ID  
        currPageId: function(callback) {  
            if(sysCom.isBrowser)  
                callback(location.href);  
            else {  
                mui.plusReady(function() {  
                    callback(plus.webview.getLaunchWebview().getURL());  
                });  
            }  
        },  
        //获取页面参数  
        getParam: function(key, callback) {  
            if(!sysCom.isBrowser) {  
                mui.plusReady(function() {  
                    var wv = plus.webview.currentWebview();  
                    var value = wv[key];  
                    callback(value);  
                });  
            } else {  
                var value = urlCom.getParam(key);  
                callback(value);  
            }  
        },  
        //获取URL所有参数  
        GetUrlParms: function() {  
            var args = new Object();  
            var query = location.search.substring(1); //获取查询串  
            var pairs = query.split("&"); //在逗号处断开  
            for(var i = 0; i < pairs.length; i++) {  
                var pos = pairs[i].indexOf('='); //查找name=value  
                if(pos == -1) continue; //如果没有找到就跳过  
                var argname = pairs[i].substring(0, pos); //提取name  
                var value = pairs[i].substring(pos + 1); //提取value  
                args[argname] = decodeURIComponent(value); //存为属性  
            }  
            return args;  
        },  
        //是否是普通浏览器打开  
        isBrowser: !mui.os.plus,  
        //loading弹出层  
        loading: function() {  
            var box = $('#loading-layout');  
            if(box.length == 0) {  
                $('body').append('<div id="loading-layout"><div class="loading"></div></div>');  
                box = $('#loading-layout');  
            }  
            var box_loading = $('#loading-layout .loading');  
            var width = box.width();  
            var height = box.height();  
            var width_loading = box_loading.width();  
            var height_loading = box_loading.height();  
            $('#loading-layout .loading').css('top', (height - height_loading) / 2 + 'px')  
            $('#loading-layout .loading').css('left', (width - width_loading) / 2 + 'px')  
            box.show();  
        },  
        //关闭弹出层  
        loadingClose: function(timer) {  
            setTimeout(function() {  
                $('#loading-layout').remove();  
            }, (timer ? timer : 0))  
        },  
        /******* http 请求 *******/  
        //请求 get  
        ajax: function(type, url, params, callback, callbackErr, el) {  
            var my = this;  
            if(!config.appCONFIG.netStatus) {  
                my.msg(config.dictionary.strings.NO_NET_POST)  
                if(callbackErr)  
                    callbackErr(config.dictionary.strings.NO_NET_POST);  
                return false;  
            }  
            var el_txt = '';  
            var timer;  
            var timer_sec = 0;  
            if(el) {  
                el_txt = $(el).text();  
                $(el).attr('disabled', true).text('正在提交');  
                timer = setInterval(function() {  
                    if(timer_sec < 3) {  
                        $(el).text($(el).text() + '.');  
                        timer_sec++;  
                    } else {  
                        $(el).text('正在提交');  
                        timer_sec = 0;  
                    }  
                }, 500);  
            }  
            //my.loading();  
            $.ajax({  
                url: url,  
                type: type, //GET  
                async: true, //或false,是否异步  
                data: params,  
                timeout: 15000, //超时时间  
                dataType: 'jsonp',  
                jsonp: "theFunction",  
                success: function(data, textStatus, jqXHR) {  
                    callback(data);  
                },  
                error: function(xhr, textStatus) {  
                    if(textStatus == "error")  
                        my.msg(config.dictionary.strings.SERVER_ERROR);  
                    else if(textStatus == "timeout")  
                        my.msg(config.dictionary.strings.TIMEOUT);  
                    else {  
                        //console.log(xhr.responseText)  
                        var jsonXhr = JSON.parse(xhr.responseText);  
                        //令牌错误重新登陆  
                        if(jsonXhr.ExceptionMessage == config.dictionary.strings.INVALID_TOKEN) {  
                            my.msg(config.dictionary.strings.INVALID_TOKEN_ERR);  
                        } else {  
                            my.msg("error:" + jsonXhr.ExceptionMessage);  
                        }  
                    }  
                    if(callbackErr)  
                        callbackErr(xhr, textStatus);  
                },  
                complete: function() {  
                    //my.loadingClose();  
                    if(el) {  
                        $(el).text(el_txt)  
                        $(el).removeAttr('disabled');  
                        clearInterval(timer);  
                    }  
                }  
            })  
        },  
        //系统自动更新  
        update: function() {  
            if(window.plus) {  
                this.updateCheck();  
            } else {  
                document.addEventListener('plusready', this.updateCheck, false);  
            }  
        },  
        //系统升级检测  
        updateCheck: function() {  
            var appVer = ''; //app版本  
            var newVer = ''; //最新版本  
            //获得当前版本  
            plus.runtime.getProperty(plus.runtime.appid, function(inf) {  
                appVer = inf.version;  
                $('.copyright').html('陕西中电新盛物流有限公司v' + appVer);  
                //console.log(1)  
                //发起新版本请求检测  
                var update_url = config.urlCONFIG.get_appupdate + "/version.txt?bust=" + (new Date().getTime());  
                //console.log(update_url)  
                $.get(update_url, {}, function(res) {  
                    var data = JSON.parse(res);  
                    newVer = data.version;  
                    fileType = 'wgt';  
                    if(appVer != newVer && parseInt(appVer.replaceAll('\\.', '')) < parseInt(newVer.replaceAll('\\.', ''))) {  
                        var waiting = plus.nativeUI.showWaiting("有新版本啦,正在下载更新 0%...", {  
                            width: '100%',  
                            height: '100%',  
                            //back: 'none',  
                            round: 1,  
                        });  
    
                        //下载更新包                   
                        var file_downing = plus.downloader.createDownload(config.urlCONFIG.get_appupdate + "/wgt/" + newVer + "." + fileType + "?_=" + (new Date().getTime()), {  
                            filename: "_doc/update/"  
                        }, function(d, status) {  
                            if(status == 200) {  
                                var _filename = d.filename;  
                                // 安装更新包  
                                plus.runtime.install(_filename, {}, function() {  
                                    //更新完毕删除更新包  
                                    plus.io.resolveLocalFileSystemURL(_filename, function(entity) {  
                                        entity.remove();  
                                    }, function(error) {  
                                        debugCom.log(error.message);  
                                    });  
                                    //如果是安卓自动重启应用,ios需要手动重启应用  
                                    if(mui.os.android) {  
                                        waiting.setTitle('更新完成,正在重新打开应用...');  
                                        setTimeout(function() {  
                                            plus.nativeUI.closeWaiting();  
                                            plus.runtime.restart();  
                                        }, 1000)  
                                    } else {  
                                        plus.nativeUI.closeWaiting();  
                                        mui.alert('更新完成,请彻底结束应用并重新打开!', '', function() {  
                                            //plus.runtime.restart();  
                                        })  
                                    }  
    
                                }, function(e) {  
                                    waiting.setTitle('更新失败:' + e.message);  
                                    setTimeout(function() {  
                                        plus.nativeUI.closeWaiting();  
                                    }, 2000);  
                                });  
                            } else {  
                                mui.toast('下载更新包出现问题:' + status)  
                            }  
                        });  
                        //下载百分比  
                        file_downing.addEventListener("statechanged", function() {  
                            var per = parseInt(file_downing.downloadedSize / file_downing.totalSize * 100);  
                            per = (per == NaN ? 0 : per);  
                            waiting.setTitle("有新版本啦,正在下载更新 " + per + "%");  
                        }, false);  
                        //开始下载  
                        file_downing.start();  
                    }  
    
                });  
            })  
        },  
        /********验证********/  
        validaCom: {  
            //验证正则  
            _regex: {  
                mobile: /^1+\d{10}$/,  
                isIDCard: /^\d{17}[\d|X|x]$|^\d{15}$/,  
                email: /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((.[a-zA-Z0-9_-]{2,3}){1,2})$/,  
            },  
            //验证手机  
            isMobile: function(txt) {  
                return this._regex.mobile.test(txt);  
            },  
            //验证邮箱  
            isEmail: function(txt) {  
                return this._regex.email.test(txt);  
            },  
            //身份证验证  
            isIDCard: function(txt) {  
                return this._regex.isIDCard.test(txt);  
            },  
        },  
        /********json操作********/  
        jsonCom: {  
            //将json转成url参数  
            jsonToUrlParam: function(param, key) {  
                var my = this;  
                var paramStr = "";  
                if(param instanceof String || param instanceof Number || param instanceof Boolean) {  
                    paramStr += "&" + key + "=" + encodeURIComponent(param);  
                } else {  
                    $.each(param, function(i) {  
                        var k = key == null ? i : key + (param instanceof Array ? "[" + i + "]" : "." + i);  
                        paramStr += '&' + my.jsonToUrlParam(this, k);  
                    });  
                }  
                return paramStr.substr(1);  
            },  
            //将url参数转成json  
            urlParamToJson: function(url) {  
                if(url.indexOf("?") > -1) {  
                    var string_a = url.split('?')[1];  
                    if(string_a.length > 0) {  
                        var string = string_a.split('&');  
                        var res = {};  
                        for(var i = 0; i < string.length; i++) {  
                            var str = string[i].split('=');  
                            res[str[0]] = str[1];  
                        }  
                        return res;  
                    } else  
                        return null;  
                } else  
                    return null;  
    
            }  
        },  
        /********数据存储********/  
        dataCom: {  
            set: function(key, data) {  
                localStorage.setItem(key, data);  
            },  
            get: function(key) {  
                return localStorage.getItem(key);  
            },  
            remove: function(key) {  
                localStorage.removeItem(key)  
            },  
            clear: function() {  
                localStorage.clear();  
            }  
        },  
        /*********** 网络监测 *************/  
        netCom: {  
            init: function() {  
                var my = this;  
                //网络检测  
                mui.plusReady(function() {  
                    if(plus.networkinfo.getCurrentType() == plus.networkinfo.CONNECTION_NONE) {  
                        config.netStatus = false;  
                        layer.msg(config.dictionary.strings.NO_NET);  
                    }  
                    document.addEventListener("netchange", my.change, false);  
                });  
            },  
            change: function() {  
                var my = this;  
                mui.plusReady(function() {  
                    //获取当前网络类型  
                    var nt = plus.networkinfo.getCurrentType();  
                    switch(nt) {  
                        case plus.networkinfo.CONNECTION_ETHERNET:  
    
                        case plus.networkinfo.CONNECTION_WIFI:  
    
                        case plus.networkinfo.CONNECTION_CELL2G:  
    
                        case plus.networkinfo.CONNECTION_CELL3G:  
    
                        case plus.networkinfo.CONNECTION_CELL4G:  
                            if(!config.netStatus) {  
                                layer.msg(config.dictionary.strings.YES_NET);  
                            }  
                            config.netStatus = true;  
                            break;  
                        default:  
                            if(config.netStatus) {  
                                layer.msg(config.dictionary.strings.NO_NET);  
                            }  
                            config.netStatus = false;  
                            break;  
                    }  
                });  
            }  
        },  
        /*********** 用户信息 *************/  
        account: {  
            getUser: function() {  
                var datauser = localStorage.getItem('datauser');  
                if(datauser) {  
                    return JSON.parse(datauser);  
                } else {  
                    return null;  
                }  
            }  
        }  
    }  
    });
收起阅读 »

HBuilder+MUI开发APP实战-司机签收系统(一)登录

mui HBuilder

如上是界面,UI自己弄去,

【HTML结构代码】-login.html

当我们点击登录的时候需要验证,要实现以下效果:

这个弹层使用的是layer插件,下面我们来上JS代码:

<script src="js/libs/require.js?v=1.0"></script>  
        <script src="js/require-config-index.js?v=1.0"></script>  
        <script src="js/app.js?v=1.0"></script>  
        <script>  
            requirejs(['common', 'config'], function(com, con) {  
                //检测升级  
                com.update();  

                //如果已经登陆,则直接进入首页  
                var user = com.account.getUser();  
                if(user)  
                {  
                    $('#carCode').val(user.vehCode);  
                    $('#mobile').val(user.driverMobile);  
                }  
                //双击退出  
                com.backExit();  

                $('button[type="submit"]').click(function() {  
                    var carCode = $('#carCode').val();  
                    var mobile = $('#mobile').val();  
                    var password = $('#password').val();  
                    if(carCode == "") {  
                        com.msg('请输入车牌号')  
                        return false;  
                    }  
                    if(mobile == "") {  
                        com.msg('请输入手机号')  
                        return false;  
                    }  
                    if(password == "") {  
                        com.msg('请输入密码')  
                        return false;  
                    }  
                    com.ajax('get', con.urlCONFIG.get_login, {  
                        'carCode': carCode,  
                        'mobile': mobile,  
                        'password': password  
                    }, function(jsonStr) {  
                        if(jsonStr) {  
                            com.dataCom.set('datauser',JSON.stringify(jsonStr));  
                            com.dataCom.set('datalogin','1');  
                            com.open('index.html');  
                        } else {  
                            com.msg('登录信息错误', 0);  
                        }  
                    }, null, this);  

                    return false;  
                })  
            });  
        </script>

细心的群众可能发现,为何没有对mui.js引用,是的,为了代码更加简洁,编码更加方便,本人将jquery和mui都压缩到了requirejs里。因为requirejs引用js都是异步的,很多童鞋在比如在使用$的时候,jquery还没加载进来,就报错了,所以本人这么做有2个好处:1,减少了文件请求数;2,全局注册了$和mui。

JS中我们多次看到com和con,com和con就是本人封装好的common.js和config.js。
common.js:主要是公共函数封装,比如系统升级,弹层,数据的存取,字符、数据处理等。
config.js:主要是封装一些静态变量。

这一节就讲到这,下节我们会详细讲解封装的关键js:common和config还有app.js,这3个脚本基本在任何APP里都可以共用,使我们开发的关键。

继续阅读 »

如上是界面,UI自己弄去,

【HTML结构代码】-login.html

当我们点击登录的时候需要验证,要实现以下效果:

这个弹层使用的是layer插件,下面我们来上JS代码:

<script src="js/libs/require.js?v=1.0"></script>  
        <script src="js/require-config-index.js?v=1.0"></script>  
        <script src="js/app.js?v=1.0"></script>  
        <script>  
            requirejs(['common', 'config'], function(com, con) {  
                //检测升级  
                com.update();  

                //如果已经登陆,则直接进入首页  
                var user = com.account.getUser();  
                if(user)  
                {  
                    $('#carCode').val(user.vehCode);  
                    $('#mobile').val(user.driverMobile);  
                }  
                //双击退出  
                com.backExit();  

                $('button[type="submit"]').click(function() {  
                    var carCode = $('#carCode').val();  
                    var mobile = $('#mobile').val();  
                    var password = $('#password').val();  
                    if(carCode == "") {  
                        com.msg('请输入车牌号')  
                        return false;  
                    }  
                    if(mobile == "") {  
                        com.msg('请输入手机号')  
                        return false;  
                    }  
                    if(password == "") {  
                        com.msg('请输入密码')  
                        return false;  
                    }  
                    com.ajax('get', con.urlCONFIG.get_login, {  
                        'carCode': carCode,  
                        'mobile': mobile,  
                        'password': password  
                    }, function(jsonStr) {  
                        if(jsonStr) {  
                            com.dataCom.set('datauser',JSON.stringify(jsonStr));  
                            com.dataCom.set('datalogin','1');  
                            com.open('index.html');  
                        } else {  
                            com.msg('登录信息错误', 0);  
                        }  
                    }, null, this);  

                    return false;  
                })  
            });  
        </script>

细心的群众可能发现,为何没有对mui.js引用,是的,为了代码更加简洁,编码更加方便,本人将jquery和mui都压缩到了requirejs里。因为requirejs引用js都是异步的,很多童鞋在比如在使用$的时候,jquery还没加载进来,就报错了,所以本人这么做有2个好处:1,减少了文件请求数;2,全局注册了$和mui。

JS中我们多次看到com和con,com和con就是本人封装好的common.js和config.js。
common.js:主要是公共函数封装,比如系统升级,弹层,数据的存取,字符、数据处理等。
config.js:主要是封装一些静态变量。

这一节就讲到这,下节我们会详细讲解封装的关键js:common和config还有app.js,这3个脚本基本在任何APP里都可以共用,使我们开发的关键。

收起阅读 »

HBuilder+MUI开发APP实战-司机签收系统(前言)

HBuilder mui

废话不多说,故事不多讲,直接上干货。
本人之前已经有3个DCloud开发APP的经验了,这次刚好有一个小的项目需要快速开发,所以边开发边写了这个教程供大家做开发参考。
本次我们还是按照Dcloud的套路来,但是我们需要用到requireJS来模块化封装下,这样模块化的好处后续我们可以体验到。
基本上使用到的JS会有:mui+Jquery+requireJS+layer+underscore

  • requirejs用来模块化封装
  • layer用来做弹窗
  • underscore用来处理数据

最终目录结构如下:

系统运行起来后的界面:

下一章,我们开始编写代码,初步完成我们这个系统。

继续阅读 »

废话不多说,故事不多讲,直接上干货。
本人之前已经有3个DCloud开发APP的经验了,这次刚好有一个小的项目需要快速开发,所以边开发边写了这个教程供大家做开发参考。
本次我们还是按照Dcloud的套路来,但是我们需要用到requireJS来模块化封装下,这样模块化的好处后续我们可以体验到。
基本上使用到的JS会有:mui+Jquery+requireJS+layer+underscore

  • requirejs用来模块化封装
  • layer用来做弹窗
  • underscore用来处理数据

最终目录结构如下:

系统运行起来后的界面:

下一章,我们开始编写代码,初步完成我们这个系统。

收起阅读 »

HBuilder开发者资源平台

mui

hCoder资源平台,有很多关于H5+和mui的视频资源,还有个类似mui的前端框架hui.

资源平台链接地址:http://www.hcoder.net/course

hCoder资源平台,有很多关于H5+和mui的视频资源,还有个类似mui的前端框架hui.

资源平台链接地址:http://www.hcoder.net/course

刚接触H5+做了个例子希望大家指点一下哪里该优化

这个是入口,首页分header(分类,可滑动),footer,内容部分通过子页面加载

<html lang="en">  

    <head>  
        <meta charset="UTF-8" />  
        <title>Document</title>  
        <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />  
        <link rel="stylesheet" type="text/css" href="css/mui.css" />  
    </head>  

    <body>  
        <header>  
            <div id="slider" class="mui-slider mui-fullscreen">  
                <div id="abc" class="mui-scroll-wrapper mui-slider-indicator mui-segmented-control mui-segmented-control-inverted">  
                    <div class="mui-scroll" id="splitH">  
                        <a class="mui-control-item mui-active" data-index="0">  
                            头条  
                        </a>  
                        <a class="mui-control-item" data-index="1">  
                            娱乐  
                        </a>  
                        <a class="mui-control-item" data-index="2">  
                            体育  
                        </a>  
                        <a class="mui-control-item" data-index="3">  
                            财经  
                        </a>  
                        <a class="mui-control-item" data-index="4">  
                            科技  
                        </a>  
                        <a class="mui-control-item" data-index="5">  
                            军事  
                        </a>  
                        <a class="mui-control-item" data-index="6">  
                            NBA  
                        </a>  
                        <a class="mui-control-item" data-index="7">  
                            国际足球  
                        </a>  
                        <a class="mui-control-item" data-index="8">  
                            中国篮球  
                        </a>  
                    </div>  
                </div>  
            </div>  
        </header>  
        <div class="mui-content" style="padding-bottom:50px;padding-top:50px;">  

        </div>  
        <footer>  
            <nav class="mui-bar mui-bar-tab">  
                <a href="main.html" index=0 class="mui-tab-item mui-active" data-index="0">  
                    <span class="mui-icon mui-icon-home"></span>  
                    <span class="mui-tab-label">首页</span>  
                </a>  
                <a href="m.html" index=1 class="mui-tab-item" data-index="1">  
                    <span class="mui-icon mui-icon mui-icon-bars"></span>  
                    <span class="mui-tab-label">新闻</span>  
                </a>  
                <a class="mui-tab-item" data-index="2">  
                    <span class="mui-icon mui-icon mui-icon-videocam"></span>  
                    <span class="mui-tab-label">视频</span>  
                </a>  
                <a href="login.html" class="mui-tab-item" data-index="3">  
                    <span class="mui-icon mui-icon mui-icon-contact"></span>  
                    <span class="mui-tab-label">我</span>  
                </a>  
            </nav>  
        </footer>  

        <script src="js/mui.js" type="text/javascript" charset="utf-8"></script>  
        <script src="js/common.js" type="text/javascript" charset="utf-8"></script>  
        <script src="js/d1.js" type="text/javascript" charset="utf-8"></script>  
    </body>  

</html>  

d1.js

mui.init({//初始化加载列表页,d2.html  
    subpages: [main.h.page('d2', {  
        top: '44px',  
        bottom: '50px'  
    })]  
});  
mui.plusReady(function() {  
indexPage.init();  

});  
var indexPage = {  
    tabIndex:0,  
    init:function(){  
        var self = this;  
        mui("#splitH").on('tap', 'a', function() {//header分类点击事件  
            var index = this.getAttribute("data-index");  
            if(index==self.tabIndex) return;//重复点击,跳过  
            self.tabIndex = index;  
            var embed = plus.webview.getWebviewById('d2');  
            embed.evalJS("parentParams("+index+");");//调用子页面方法,加载相应列表  
        });       
    },  
    go:function(i){//子类左滑/右滑改变分类的颜色  
        mui('#abc').scroll().scrollTo(-50*i,0,100);//100毫秒滚动  
        mui('#splitH a')[this.tabIndex].classList.remove('mui-active');  
        mui('#splitH a')[i].classList.add('mui-active');  
        this.tabIndex = i;  
    }  
};  

d2.html

<!DOCTYPE html>  
<html>  

    <head>  
        <meta charset="utf-8">  
        <title>Hello MUI</title>  
        <meta name="viewport" content="width=device-width, initial-scale=1,maximum-scale=1,user-scalable=no">  
        <meta name="apple-mobile-web-app-capable" content="yes">  
        <meta name="apple-mobile-web-app-status-bar-style" content="black">  

        <link rel="stylesheet" href="css/mui.css">  
        <style>  
            html,  
            body {  
                background-color: #efeff4;  
            }  

            .mui-pull-top-tips {  
                z-index: 999999;  
                position: absolute;  
                top: -20px;  
                left: 50%;  
                margin-left: -25px;  
                width: 40px;  
                height: 40px;  
                border-radius: 100%;  
            }  

            .mui-pull-top-wrapper {  
                width: 42px;  
                height: 42px;  
                display: block;  
                text-align: center;  
                background-color: #efeff4;  
                border: 1px solid #ddd;  
                border-radius: 25px;  
                background-clip: padding-box;  
                box-shadow: 0 4px 10px #bbb;  
                overflow: hidden;  
            }  

            .mui-pull-top-tips.mui-transitioning {  
                -webkit-transition-duration: 200ms;  
                transition-duration: 200ms;  
            }  

            .mui-pull-top-tips .mui-pull-loading {  
                margin: 0;  
            }  

            .mui-pull-top-wrapper .mui-icon,  
            .mui-pull-top-wrapper .mui-spinner {  
                margin-top: 7px;  
            }  

            .mui-pull-bottom-tips {  
                text-align: center;  
                background-color: #efeff4;  
                font-size: 15px;  
                line-height: 40px;  
                color: #777;  
            }  

            .mui-pull-top-canvas {  
                overflow: hidden;  
                background-color: #fafafa;  
                border-radius: 40px;  
                box-shadow: 0 4px 10px #bbb;  
                width: 40px;  
                height: 40px;  
                margin: 0 auto;  
            }  

            .mui-pull-top-canvas canvas {  
                width: 40px;  
            }  

            .ud,  
            .ud p {  
                padding: 5px;  
                color: #000;  
            }  

            .ud a {  
                width: 33.3333%;  
                float: left;  
            }  

            .ud img {  
                width: 100%;  
            }  

            #uda {  
                margin: 0;  
            }  

            #pp div {  
                border: 0;  
            }  
        </style>  
    </head>  

    <body>  
        <div class="mui-content">  
            <div id="scroll1" class="mui-scroll-wrapper">  
                <div class="mui-scroll">  
                    <ul class="mui-table-view">  

                    </ul>  
                </div>  
            </div>  
        </div>  
    </body>  
    <script src="js/mui.js"></script>  
    <script src="js/mui.pullToRefresh.js"></script>  
    <script src="js/mui.pullToRefresh.material.js"></script>  
    <script>  
        mui.init();  
        mui.plusReady(function() {  
            detail.init();  
        });  
        var detail = {  
            tabIndex: 0,  
            count: 3,  
            pullObj: '',  
            mainPage: '',  
            titleName: ['头条', '娱乐', '体育', '财经', '科技', '军事', 'NBA', '国际足球','中国篮球'],  
            init: function() {  
                this.mainPage = plus.webview.getLaunchWebview();  
                this.setScroll();  
                this.pullDown();  
                this.initGallery();  
            },  
            setTabIndex: function(index) {  
                this.tabIndex = index;  
            },  
            setScroll: function() {  
                var self = this;  
                mui('.mui-scroll-wrapper').scroll({  
                    bounce: false,  
                    indicators: false, //是否显示滚动条  
                    deceleration: 0.003 //滚动效果越大越灵敏  
                });  
                //循环初始化所有下拉刷新,上拉加载。  
                self.pullObj = mui('.mui-scroll').pullToRefresh({  
                    down: {  
                        callback: function() {  
                            var _self = this;  
                            setTimeout(function() {  
                                var ul = _self.element.querySelector('.mui-table-view');  
                                ul.innerHTML = "";  
                                ul.appendChild(self.getData());  
                                //ul.removeChild(ul.firstChild).insertBefore(self.getData(), ul.firstChild);  
                                _self.endPullDownToRefresh();  
                            }, 1000);  
                        }  
                    },  
                    up: {  
                        callback: function() {  
                            var _self = this;  
                            setTimeout(function() {  
                                var ul = _self.element.querySelector('.mui-table-view');  
                                ul.appendChild(self.getData());  
                                _self.endPullUpToRefresh();  
                            }, 1000);  
                        }  
                    }  
                });  
            },  
            pullDown: function() {  
                this.pullObj.pullDownLoading();  
            },  
            getData: function() {//获取数据  
                console.log('开始加载...');  
                var fragment = document.createDocumentFragment();  
                var li;  
                for(var i = 0; i < this.count; i++) {  
                    li = document.createElement('li');  
                    li.className = 'mui-table-view-cell';  
                    li.innerHTML = this.titleName[this.tabIndex] + '选项卡子项';  
                    fragment.appendChild(li);  
                }  
                return fragment;  

            }  

        };  
        document.addEventListener("swipeleft", function() {  
            if(detail.tabIndex == detail.titleName.length - 1) return;  
            detail.tabIndex += 1;  
            detail.pullDown();  
            detail.mainPage.evalJS("indexPage.go(" + detail.tabIndex + ");");  
            console.log("你向左滑动了");  
        });  
        document.addEventListener("swiperight", function() {  
            if(detail.tabIndex == 0) return;  
            detail.tabIndex += -1;  
            detail.pullDown();  
            detail.mainPage.evalJS("indexPage.go(" + detail.tabIndex + ");");  
            console.log("你向右滑动了");  
        });  

        function parentParams(i) {//供父类调用  
            detail.setTabIndex(i);  
            detail.pullDown();  
        }  

    </script>  

</html>  

哪里有不足的地方希望大家指出

继续阅读 »

这个是入口,首页分header(分类,可滑动),footer,内容部分通过子页面加载

<html lang="en">  

    <head>  
        <meta charset="UTF-8" />  
        <title>Document</title>  
        <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />  
        <link rel="stylesheet" type="text/css" href="css/mui.css" />  
    </head>  

    <body>  
        <header>  
            <div id="slider" class="mui-slider mui-fullscreen">  
                <div id="abc" class="mui-scroll-wrapper mui-slider-indicator mui-segmented-control mui-segmented-control-inverted">  
                    <div class="mui-scroll" id="splitH">  
                        <a class="mui-control-item mui-active" data-index="0">  
                            头条  
                        </a>  
                        <a class="mui-control-item" data-index="1">  
                            娱乐  
                        </a>  
                        <a class="mui-control-item" data-index="2">  
                            体育  
                        </a>  
                        <a class="mui-control-item" data-index="3">  
                            财经  
                        </a>  
                        <a class="mui-control-item" data-index="4">  
                            科技  
                        </a>  
                        <a class="mui-control-item" data-index="5">  
                            军事  
                        </a>  
                        <a class="mui-control-item" data-index="6">  
                            NBA  
                        </a>  
                        <a class="mui-control-item" data-index="7">  
                            国际足球  
                        </a>  
                        <a class="mui-control-item" data-index="8">  
                            中国篮球  
                        </a>  
                    </div>  
                </div>  
            </div>  
        </header>  
        <div class="mui-content" style="padding-bottom:50px;padding-top:50px;">  

        </div>  
        <footer>  
            <nav class="mui-bar mui-bar-tab">  
                <a href="main.html" index=0 class="mui-tab-item mui-active" data-index="0">  
                    <span class="mui-icon mui-icon-home"></span>  
                    <span class="mui-tab-label">首页</span>  
                </a>  
                <a href="m.html" index=1 class="mui-tab-item" data-index="1">  
                    <span class="mui-icon mui-icon mui-icon-bars"></span>  
                    <span class="mui-tab-label">新闻</span>  
                </a>  
                <a class="mui-tab-item" data-index="2">  
                    <span class="mui-icon mui-icon mui-icon-videocam"></span>  
                    <span class="mui-tab-label">视频</span>  
                </a>  
                <a href="login.html" class="mui-tab-item" data-index="3">  
                    <span class="mui-icon mui-icon mui-icon-contact"></span>  
                    <span class="mui-tab-label">我</span>  
                </a>  
            </nav>  
        </footer>  

        <script src="js/mui.js" type="text/javascript" charset="utf-8"></script>  
        <script src="js/common.js" type="text/javascript" charset="utf-8"></script>  
        <script src="js/d1.js" type="text/javascript" charset="utf-8"></script>  
    </body>  

</html>  

d1.js

mui.init({//初始化加载列表页,d2.html  
    subpages: [main.h.page('d2', {  
        top: '44px',  
        bottom: '50px'  
    })]  
});  
mui.plusReady(function() {  
indexPage.init();  

});  
var indexPage = {  
    tabIndex:0,  
    init:function(){  
        var self = this;  
        mui("#splitH").on('tap', 'a', function() {//header分类点击事件  
            var index = this.getAttribute("data-index");  
            if(index==self.tabIndex) return;//重复点击,跳过  
            self.tabIndex = index;  
            var embed = plus.webview.getWebviewById('d2');  
            embed.evalJS("parentParams("+index+");");//调用子页面方法,加载相应列表  
        });       
    },  
    go:function(i){//子类左滑/右滑改变分类的颜色  
        mui('#abc').scroll().scrollTo(-50*i,0,100);//100毫秒滚动  
        mui('#splitH a')[this.tabIndex].classList.remove('mui-active');  
        mui('#splitH a')[i].classList.add('mui-active');  
        this.tabIndex = i;  
    }  
};  

d2.html

<!DOCTYPE html>  
<html>  

    <head>  
        <meta charset="utf-8">  
        <title>Hello MUI</title>  
        <meta name="viewport" content="width=device-width, initial-scale=1,maximum-scale=1,user-scalable=no">  
        <meta name="apple-mobile-web-app-capable" content="yes">  
        <meta name="apple-mobile-web-app-status-bar-style" content="black">  

        <link rel="stylesheet" href="css/mui.css">  
        <style>  
            html,  
            body {  
                background-color: #efeff4;  
            }  

            .mui-pull-top-tips {  
                z-index: 999999;  
                position: absolute;  
                top: -20px;  
                left: 50%;  
                margin-left: -25px;  
                width: 40px;  
                height: 40px;  
                border-radius: 100%;  
            }  

            .mui-pull-top-wrapper {  
                width: 42px;  
                height: 42px;  
                display: block;  
                text-align: center;  
                background-color: #efeff4;  
                border: 1px solid #ddd;  
                border-radius: 25px;  
                background-clip: padding-box;  
                box-shadow: 0 4px 10px #bbb;  
                overflow: hidden;  
            }  

            .mui-pull-top-tips.mui-transitioning {  
                -webkit-transition-duration: 200ms;  
                transition-duration: 200ms;  
            }  

            .mui-pull-top-tips .mui-pull-loading {  
                margin: 0;  
            }  

            .mui-pull-top-wrapper .mui-icon,  
            .mui-pull-top-wrapper .mui-spinner {  
                margin-top: 7px;  
            }  

            .mui-pull-bottom-tips {  
                text-align: center;  
                background-color: #efeff4;  
                font-size: 15px;  
                line-height: 40px;  
                color: #777;  
            }  

            .mui-pull-top-canvas {  
                overflow: hidden;  
                background-color: #fafafa;  
                border-radius: 40px;  
                box-shadow: 0 4px 10px #bbb;  
                width: 40px;  
                height: 40px;  
                margin: 0 auto;  
            }  

            .mui-pull-top-canvas canvas {  
                width: 40px;  
            }  

            .ud,  
            .ud p {  
                padding: 5px;  
                color: #000;  
            }  

            .ud a {  
                width: 33.3333%;  
                float: left;  
            }  

            .ud img {  
                width: 100%;  
            }  

            #uda {  
                margin: 0;  
            }  

            #pp div {  
                border: 0;  
            }  
        </style>  
    </head>  

    <body>  
        <div class="mui-content">  
            <div id="scroll1" class="mui-scroll-wrapper">  
                <div class="mui-scroll">  
                    <ul class="mui-table-view">  

                    </ul>  
                </div>  
            </div>  
        </div>  
    </body>  
    <script src="js/mui.js"></script>  
    <script src="js/mui.pullToRefresh.js"></script>  
    <script src="js/mui.pullToRefresh.material.js"></script>  
    <script>  
        mui.init();  
        mui.plusReady(function() {  
            detail.init();  
        });  
        var detail = {  
            tabIndex: 0,  
            count: 3,  
            pullObj: '',  
            mainPage: '',  
            titleName: ['头条', '娱乐', '体育', '财经', '科技', '军事', 'NBA', '国际足球','中国篮球'],  
            init: function() {  
                this.mainPage = plus.webview.getLaunchWebview();  
                this.setScroll();  
                this.pullDown();  
                this.initGallery();  
            },  
            setTabIndex: function(index) {  
                this.tabIndex = index;  
            },  
            setScroll: function() {  
                var self = this;  
                mui('.mui-scroll-wrapper').scroll({  
                    bounce: false,  
                    indicators: false, //是否显示滚动条  
                    deceleration: 0.003 //滚动效果越大越灵敏  
                });  
                //循环初始化所有下拉刷新,上拉加载。  
                self.pullObj = mui('.mui-scroll').pullToRefresh({  
                    down: {  
                        callback: function() {  
                            var _self = this;  
                            setTimeout(function() {  
                                var ul = _self.element.querySelector('.mui-table-view');  
                                ul.innerHTML = "";  
                                ul.appendChild(self.getData());  
                                //ul.removeChild(ul.firstChild).insertBefore(self.getData(), ul.firstChild);  
                                _self.endPullDownToRefresh();  
                            }, 1000);  
                        }  
                    },  
                    up: {  
                        callback: function() {  
                            var _self = this;  
                            setTimeout(function() {  
                                var ul = _self.element.querySelector('.mui-table-view');  
                                ul.appendChild(self.getData());  
                                _self.endPullUpToRefresh();  
                            }, 1000);  
                        }  
                    }  
                });  
            },  
            pullDown: function() {  
                this.pullObj.pullDownLoading();  
            },  
            getData: function() {//获取数据  
                console.log('开始加载...');  
                var fragment = document.createDocumentFragment();  
                var li;  
                for(var i = 0; i < this.count; i++) {  
                    li = document.createElement('li');  
                    li.className = 'mui-table-view-cell';  
                    li.innerHTML = this.titleName[this.tabIndex] + '选项卡子项';  
                    fragment.appendChild(li);  
                }  
                return fragment;  

            }  

        };  
        document.addEventListener("swipeleft", function() {  
            if(detail.tabIndex == detail.titleName.length - 1) return;  
            detail.tabIndex += 1;  
            detail.pullDown();  
            detail.mainPage.evalJS("indexPage.go(" + detail.tabIndex + ");");  
            console.log("你向左滑动了");  
        });  
        document.addEventListener("swiperight", function() {  
            if(detail.tabIndex == 0) return;  
            detail.tabIndex += -1;  
            detail.pullDown();  
            detail.mainPage.evalJS("indexPage.go(" + detail.tabIndex + ");");  
            console.log("你向右滑动了");  
        });  

        function parentParams(i) {//供父类调用  
            detail.setTabIndex(i);  
            detail.pullDown();  
        }  

    </script>  

</html>  

哪里有不足的地方希望大家指出

收起阅读 »

mui plusReady 不触发问题。

添加。
<script src="html5plus://ready"></script>

添加。
<script src="html5plus://ready"></script>

看到网上介绍的HBuilder的介绍,下载下来尝试. 唉。

看到网上介绍的HBuilder的介绍,下载下来尝试, 装上去试下。

  1. 绿色版本,很不错啊。
    安装上去,运行,界面很简介也不错。
    提示很贴心,不必webStorm 差。

  2. 看一看内存,晕死了都。 700M. 只打开了一个文件。
    占用内存,是当时放弃webStrom的主要原因。
    唉,都是Eclipse害的。
    果断放弃HBuilder, 还是用我的sublime吧。

  3. sublime内存占用没超过 100M, 一般稳定在 60M左右,速度又快。

    现在是,只要看到 Eclipse 就不敢用啊!
    开Eclipse之类的,编译其它程序代码,立马报告 内存不足。

    公司系统加密,只能用XP, 上不了大内存啊.

继续阅读 »

看到网上介绍的HBuilder的介绍,下载下来尝试, 装上去试下。

  1. 绿色版本,很不错啊。
    安装上去,运行,界面很简介也不错。
    提示很贴心,不必webStorm 差。

  2. 看一看内存,晕死了都。 700M. 只打开了一个文件。
    占用内存,是当时放弃webStrom的主要原因。
    唉,都是Eclipse害的。
    果断放弃HBuilder, 还是用我的sublime吧。

  3. sublime内存占用没超过 100M, 一般稳定在 60M左右,速度又快。

    现在是,只要看到 Eclipse 就不敢用啊!
    开Eclipse之类的,编译其它程序代码,立马报告 内存不足。

    公司系统加密,只能用XP, 上不了大内存啊.

收起阅读 »

MUI仿咸鱼底部tabbar圆形发布按钮样式

tabbar

<nav class="mui-bar mui-bar-tab footer-nav">
<a class="mui-tab-item mui-active" href="#tabbar">
<span class="mui-icon icon">&#xe62b;</span>
<span class="mui-tab-label">首页</span>
</a>
<a class="mui-tab-item" href="#tabbar-with-chat">
<span class="mui-icon icon">&#xe602;</span>
<span class="mui-tab-label">分类</span>
</a>
<a class="mui-tab-item tab-item-center" href="#tabbar-with-contact">
<span class="mui-icon plus"><span class="icon">&#xe60d;</span></span>
<span class="mui-tab-label tab-label">发布</span>
</a>
<a class="mui-tab-item" href="#tabbar-with-contact">
<span class="mui-icon icon">&#xe647;</span>
<span class="mui-tab-label">消息</span>
</a>
<a class="mui-tab-item" href="#tabbar-with-map">
<span class="mui-icon icon">&#xe655;</span>
<span class="mui-tab-label">我的</span>
</a>
</nav>

.footer-nav .tab-item-center{
position:relative;
overflow:visible;
text-align:center;
}
.footer-nav .tab-item-center .plus{
display:inline-block;
width:100%;
color:#fff;
position:absolute;
left:0;
top:-25px;
}
.footer-nav .tab-item-center .plus .icon{
width:auto;
height:auto;
padding:10px;
background:#1ba9ba;
border-radius:50%;
border:3px solid #fff;
box-shadow: 0 -2px 3px rgba(100,100,100,.4);
}
.footer-nav .tab-item-center .tab-label{
margin-top:25px;
}

继续阅读 »

<nav class="mui-bar mui-bar-tab footer-nav">
<a class="mui-tab-item mui-active" href="#tabbar">
<span class="mui-icon icon">&#xe62b;</span>
<span class="mui-tab-label">首页</span>
</a>
<a class="mui-tab-item" href="#tabbar-with-chat">
<span class="mui-icon icon">&#xe602;</span>
<span class="mui-tab-label">分类</span>
</a>
<a class="mui-tab-item tab-item-center" href="#tabbar-with-contact">
<span class="mui-icon plus"><span class="icon">&#xe60d;</span></span>
<span class="mui-tab-label tab-label">发布</span>
</a>
<a class="mui-tab-item" href="#tabbar-with-contact">
<span class="mui-icon icon">&#xe647;</span>
<span class="mui-tab-label">消息</span>
</a>
<a class="mui-tab-item" href="#tabbar-with-map">
<span class="mui-icon icon">&#xe655;</span>
<span class="mui-tab-label">我的</span>
</a>
</nav>

.footer-nav .tab-item-center{
position:relative;
overflow:visible;
text-align:center;
}
.footer-nav .tab-item-center .plus{
display:inline-block;
width:100%;
color:#fff;
position:absolute;
left:0;
top:-25px;
}
.footer-nav .tab-item-center .plus .icon{
width:auto;
height:auto;
padding:10px;
background:#1ba9ba;
border-radius:50%;
border:3px solid #fff;
box-shadow: 0 -2px 3px rgba(100,100,100,.4);
}
.footer-nav .tab-item-center .tab-label{
margin-top:25px;
}

收起阅读 »

原生图片剪裁,利用cropper.js插件和5+的图片压缩实现,可直接输出base64或保存本地图片。

图片压缩 头像裁剪

如题。理论上完全兼容android和ios。
cropper.js应该很多人用过,是web端图片剪裁的利器。可以对图片进行base64编码,方便上传后台。
5+中的api。plus.zip.compressImage接口,压缩图片保存本地的效率很高,但是没有图形化界面。
于是,我就想 ,把这两个结合起来,做出图形化剪裁的功能来,实现本地存储和base64输出。
结果发现,天作之合,太简单了。
我想说,也许是目前最好的剪裁方案了。(不知道有没有别人提出过这个方法,我先小得意一下)

本人非专业前端,js弱鸡,不会做插件化开发。只能流水式写方法了。

不废话,直接页面代码,我把每一步都写得非常详细,再菜的人应该都能看懂了(而且确实非常简单)。
召唤这个页面的页面代码我就不放了。相信没有那么菜的鸡。

<!DOCTYPE html>  
<html>  
    <head>  
        <meta name="viewport" content="width=device-width, initial-scale=1,maximum-scale=1, user-scalable=no">  
        <meta name="apple-mobile-web-app-capable" content="yes">  
        <meta name="apple-mobile-web-app-status-bar-style" content="black">  
        <meta charset="utf-8">  
        <title></title>  
        <link rel="stylesheet" href="css/cropper.min.css" />  
        <link rel="stylesheet" href="css/mui.min.css" />  
        <style>  
            #redo{  
                position: fixed;  
                bottom: 20px;  
                left :20px;  
                font-size: 30px;  
                color: #FFFFFF;  
            }  
            #undo{  
                position: fixed;  
                bottom: 20px;  
                right :20px;  
                font-size: 30px;  
                color: #FFFFFF;  
            }  
            html{  
                background: #000000;  
            }  
            .holdcenter{  
                background-color: #007AFF;  
                order:auto;  
                flex: 0 1 auto;  
                -webkit-flex: 0 1 auto;  
                align-self: auto;  
                overflow: hidden;  
            }  
            .outer-box{  
                display: flex;  
                display: -webkit-flex;  
                /*height: 100%;*/  
                /*border: 1px solid #000000;*/  
                background-color: #000000;  
                flex-direction: row;  
                flex-flow: row wrap;  
                -webkit-flex-flow: row wrap;  
                /*justify-content: flex-start;*/  
               justify-content: center;  
               align-items: center;  
            }  
        </style>  
    </head>  
    <body>  
        <header class="mui-bar mui-bar-transparent">  
          <!--<h1 id="patientId" class="mui-title">截取头像</h1>-->  
          <a id="save"  class="mui-icon mui-icon-checkmarkempty mui-pull-right" style="font-size: 3rem;color: #FFFFFF;"></a>  
        </header>  
        <div style="" class="outer-box mui-fullscreen">  
            <div style="" class="holdcenter">  
                <img style="width: 100%;" id="image" src="images/cbd.jpg">  
            </div>  
            <a id="redo" class=" mui-pull-left"><span class="mui-icon mui-icon-redo"></span></a>  
            <a id="undo" class=" mui-pull-right"><span class="mui-icon mui-icon-undo"></span></a>  
        </div>  
        <script type="text/javascript" src="js/mui.min.js" ></script>  
        <script type="text/javascript" src="js/cropper.min.js" ></script>  
        <script>  
            /**  
             * 本功能灵感来源于 crooper.js。github地址请看js文件  
             * 利用cropper.js进行图片剪裁。支持旋转。  
             * 可以直接获取剪裁后的base64。  
             * 也可以利用cropper的方法,可以获取一系列参数,借用5+API,  
             * 可以直接保存本地图片,效率非常高。  
             * 有对cropper.js熟悉的可以进一步研究修改,提供更多可用功能  
             * 理论上完全兼容android和ios系统。  
             */  
            mui.init({  
                hardwareAccelerated:true,  
            });  

            var image = document.getElementById('image');//获取图片元素  
            var cropper = null;  
            var resImg = null;      //剪切后图片base64编码资源  

            //初始化控件的方法  
            function initCropper(){  
                cropper = new Cropper(image, {  
                    //aspectRatio: 1/1,16/9,4/3,2/3,NaN(自定义)  
                    aspectRatio: NaN,   //不锁定 "剪裁框" 比例(自定义)  
                    dragMode:'crop',  
                    rotatable:true, //是否允许旋转  
                    minCropBoxWidth:0,  
                    minCropBoxHeight:0,  
                    minCanvasWidth:0,  
                    minCanvasHeight:0,  
                    minContainerWidth:200,  
                    minContainerHeight:200,  
                    cropBoxResizable: true, //是否允许 调整 剪裁框 的大小  
                    crop: function(data) {  
                     }  
                });  
            }// initCropper  end  

            //保存按钮监听  
            document.getElementById("save").addEventListener("tap",function(){  
                //传入true,获取base64字串,不传或者传入false保存本地文件,获取保存路径。  
                getImg();  
            });  
            //右旋转按钮监听  
            document.getElementById("redo").addEventListener("tap",function(){  
                cropper.rotate(90);  
                //这里的旋转角度90数据可自行定义,比方说:15,30,45。支持每次旋转1度  
                //但是考虑到5+api的旋转只支持90一个单位,所以设定每次旋转90度。  
                //有兴趣可以去cropper的范列网站https://fengyuanchen.github.io/cropperjs/自己定义旋转角度试试。  
                //但是227行的5+api旋转参数如何对应需要动脑筋。90度旋转对用户来说应该足够了。  
            });  
            //左旋转按钮监听  
            document.getElementById("undo").addEventListener("tap",function(){  
                cropper.rotate(-90);  
            });  

            //在选择或者拍摄完成后打开此裁剪页面并把图片路径传递到此页面  
            mui.plusReady(function(){  
                //imgSrc是webview的扩展参数传过来的图片路径,用io方法转换成本地绝对路径  
                image.src = plus.io.convertLocalFileSystemURL(plus.webview.currentWebview().imgSrc);  
                //image.src = "images/muwu.jpg";  

                initCropper();  //初始化cropper控件  
            });//plusReady  end  

            /**  
             * 获取图片的方法  
             * @param {Boolean} flag  
             */  
            function getImg(flag){  
                //如果flag传入true,生成base64资源     

                if(flag){  
                    resImg =  cropper.getCroppedCanvas({  
                          width: 300,  
                          height: 300  
                    }).toDataURL();  
                    //纯cropper.js的功能  
                    //resImg 就是base64字符串,可以返回给需要的页面或者上传  
                    console.log(resImg);  
                    //like is “data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAAFkCAYAAACadgZ0AAAgAElEQVR4XtS9”  
                }else{  
                //否则生成本地图片  
                    //cropper提供的方法,可以获取剪裁范围内的图片的信息,这一个方法就够了。下面的其他方法仅供参考  
                    var cropeddata = cropper.getData();               
                    //console.log(JSON.stringify(cropeddata));  
                    /* 像这样  
                     * {"x":793.6,      /左边距,像素,单位px  
                     * "y":297.59999999999997,  //上边距  
                    *   "width":2380.7999999999997,     //选中的部分图片的宽度,px,Number  
                    *   "height":2380.7999999999997,    //选中部分图片的高度,px,Number  
                    *   "rotate":0,                     //旋转度数,Number  
                    *   "scaleX":1,                     //x轴缩放比例Number  
                    *   "scaleY":1}                     //y轴缩放比例Number  
                    */  

                    //原始图片信息  
                    var sourceImgDate = cropper.getImageData();  
                    //console.log(JSON.stringify(sourceImgDate));  
                    /* 像这样  
                     * {"naturalWidth":3968,        //原始图片宽度,px,像素  
                        "naturalHeight":2976,       //原始图片高度,px  
                        "aspectRatio":1.3333333333333333,   //纵横比,高宽比  
                        "width":360,                        //在页面上的显示尺寸  
                        "height":270,  
                        "left":0,  
                        "top":0}  
                     */  

                    //获取容器(img元素)的信息  
                    var containerData = cropper.getContainerData();  
                    //console.log(JSON.stringify(containerData));  
                    /*  像这样  
                     * {"width":360,"height":276}  
                     */  

                    //剪裁框的信息  
                    var cropData = cropper.getCropBoxData();  
                    //console.log(JSON.stringify(cropData));  
                    /*  像这样  
                     * {"left":72,"top":30,  
                     *  "width":216,  
                     * "height":216}  
                     */  

                    //获取canvers的信息  
                    var canversData = cropper.getCanvasData();  
                    //console.log(JSON.stringify(canversData));  
                    /*  像这样  
                     * {"left":0,"top":3,  
                     * "width":360,  
                     * "height":270,  
                     * "naturalWidth":3968,  
                     * "naturalHeight":2976}  
                     */  

                    //接下来使用H5+的图片压缩压缩转换API来完成剪裁和压缩  
                    //http://www.html5plus.org/doc/zh_cn/zip.html  
                    //准备工作  
                    //JSON对象,图片裁剪区域的参数  
                    //注意:4个属性我们都已经通过cropper的getData()方法直接获取到了值,是不是很简单呢  
                    //直接组织数据吧  
                    var ClipImageOptions = {  
                        top:cropeddata.y ,      //(String 类型 )图片裁剪区域与原图片上边界的偏移距离  
                                    //支持像素值(如"10px")、百分比(如"10%");默认值为"0px"。 注意:如果top值超出原图片高度,则图片裁剪失败。  

                        left:cropeddata.x ,     //(Stirng 类型 )图片裁剪区域与原图片左边界的偏移距离  
                                    //支持像素值(如"10px")、百分比(如"10%");默认值为"0px"。 注意:如果left值超出原图片宽度,则图片裁剪失败。  

                        width:cropeddata.width,         //(String 类型 )图片裁剪区域的宽度  
                                    //支持像素值(如"100px")、百分比(如"50%")、自动计算(如"auto",即从left位置到图片右边界的宽度);默认值为"auto"。 注意:如果left值加width值超出原图片宽度,则使用"auto"值进行裁剪。  

                        height:cropeddata.height    //(String 类型 )图片裁剪区域的高度  
                                    //支持像素值(如"100px")、百分比(如"50%")、自动计算(如"auto",即从top位置到图片下边界的高度);默认值为"auto"。 注意:如果top值加height值超出原图片高度,则使用"auto"值进行裁剪。  
                    }  

                    //处理旋转角度,因为5+api不接受负值  
                    var rotate = 0;//默认值  
                    if(cropeddata.rotate >= 0){  
                        rotate = cropeddata.rotate;  
                    }else{  
                        switch(cropeddata.rotate){  
                            case -90:  
                                rotate = 270;  
                                break;  
                            case -180:  
                                rotate = 180;  
                                break;  
                            case -270:  
                                rotate = 90;  
                                break;  
                            default:  
                                rotate = 0;   
                        }  
                    }  

                    //获取图片格式                  
                    var format = image.src.substring(image.src.lastIndexOf(".")+1);  
                    //console.log(format);  
                    //根据日期生成图片名称  
                    var d = new Date();                   
                    var picName = d.getFullYear()+""+(d.getMonth()+1)+""+d.getDate()+""+d.getHours()+""+d.getMinutes()+""+d.getSeconds();  
                    var fullname = picName+"."+format;  
                    console.log(fullname); //完整图片名称  

                    //JSON对象,配置图片压缩转换的参数  
                    var imgOption = {src:image.src,     //原始图片路径  
                        dst: "../doc/"+fullname ,//(String 类型 )压缩转换目标图片的路径,这里保存到 私有目录doc  
                                                    //如“/sdcard/Android/data/io.dcloud.HBuilder/.HBuilder/apps/HBuilder/doc”。  
                        overwrite:true,     //覆盖生成新文件  
                        format: '',//(String 类型 )压缩转换后的图片格式,支持"jpg"、"png",如果未指定则使用源图片的格式。  
                        quality:50,//(Number 类型 )压缩图片的质量,可以自己调整  
                                        //取值范围为1-100,1表示使用最低的图片质量(转换后的图片文件最小)、100表示使用最高的图片质量(转换后的图片文件最大); 默认值为50。  
                        width:'auto',       //(String 类型 )缩放图片的宽度  
                                    //支持像素值(如"100px")、百分比(如"50%")、自动计算(如"auto",即根据height与源图高的缩放比例计算,若未设置height则使用源图高度); 默认值为"auto"。 注意:若设置了width属性值不合法(如"0px"),则不对图片进行缩放操作。  

                        height:'auto',  //(String 类型 )缩放图片的高度  
                                        //支持像素值(如"100px")、百分比(如"50%")、自动计算(如"auto",即根据width与源图宽的缩放比例计算,若未设置width则使用源图高度); 默认值为"auto"。 注意:若设置了height属性值不合法(如"0px"),则不对图片进行缩放操作。  

                        rotate:rotate,      //(Number 类型 )旋转图片的角度  
                                        //支持值:90-表示旋转90度;180-表示旋转180度;270-表示旋转270度。 注意:若设置rotate属性值不合法,则不对图片进行旋转操作。  
                        clip: ClipImageOptions          //(ClipImageOptions 类型(json对象) )裁剪图片的区域  
                                        //值参考ClipImageOptions定义,若设置clip属性值不合法,则不对图片进行裁剪操作。  
                    }  

                    //开始剪裁  
                    plus.zip.compressImage(  
                            imgOption,      //JSON对象,配置图片压缩转换的参数  
                            function(){                                                                           
                                //console.log(imgOption.dst);                         
                                //console.log("压缩成功");  
                                mui.toast("图片已保存到:"+imgOption.dst,{duration:"long"});  
                                //如果想要绝对路径  
                                var path=plus.io.convertLocalFileSystemURL(imgOption.dst);  
                                console.log(path);  
                                //后续处理  
                                //将imgOption.dst或者path传递给父页面,用来显示或者上传后台,请自行决定  
                                //mui.fire(plus.webview.currentWebview().opener(),"avart",{img:imgOption.dst});  
                            },function(error){                        
                                console.log("压缩失败");  

                            }  
                        );  

                    //如果不是存到doc目录,而是其他比较复杂的目录,比如根目录  
                    //用下面的方法。替换plus.io.PRIVATE_DOC就可以  
                    /*plus.io.requestFileSystem(plus.io.PRIVATE_DOC,function(fs){  
                        var filepath = fs.root.fullPath;  
                        //console.log(fs.root.fullPath);  
                        var directEntery = fs.root;  
                        //创建目录,其实这一段并不是必须的,  
                        //plus.zip.compressImage自己会创建文件夹  
                        //相对目录你可以在上面imgOption.dst里面直接写上相对路径"../doc"+fullname  
                        directEntery.getDirectory(  
                                filepath,  
                                {create:true,exclusive:false},  
                                function(direnter){  
                                    //如果文件夹已经存在,也会进入这里,所以就不用toast显示了  
                                    //mui.toast("创建doc文件夹成功");  
                                },function(e){  
                                    mui.toast("创建文件夹失败:"+e.message);  
                                    mui.back();  
                                }  
                        );  

                        //把目标路径更新到json对象  
                        imgOption.dst = filepath+fullname;  
                        //开始压缩图片  
                        plus.zip.compressImage(imgOption,  
                            function(){                                                                           
                                //console.log(imgOption.dst);                         
                                //console.log("压缩成功");  
                                mui.toast("图片已保存到:"+imgOption.dst,{duration:long});  
                                //将imgOption.dst传递给父页面,用来显示或者上传后台  
                            },function(error){                        
                                console.log("压缩失败");  

                        });  
                    }); */  

                }  

                //最后退出剪裁页面  
                mui.back();  
            }         

        </script>  
    </body>  
</html>
继续阅读 »

如题。理论上完全兼容android和ios。
cropper.js应该很多人用过,是web端图片剪裁的利器。可以对图片进行base64编码,方便上传后台。
5+中的api。plus.zip.compressImage接口,压缩图片保存本地的效率很高,但是没有图形化界面。
于是,我就想 ,把这两个结合起来,做出图形化剪裁的功能来,实现本地存储和base64输出。
结果发现,天作之合,太简单了。
我想说,也许是目前最好的剪裁方案了。(不知道有没有别人提出过这个方法,我先小得意一下)

本人非专业前端,js弱鸡,不会做插件化开发。只能流水式写方法了。

不废话,直接页面代码,我把每一步都写得非常详细,再菜的人应该都能看懂了(而且确实非常简单)。
召唤这个页面的页面代码我就不放了。相信没有那么菜的鸡。

<!DOCTYPE html>  
<html>  
    <head>  
        <meta name="viewport" content="width=device-width, initial-scale=1,maximum-scale=1, user-scalable=no">  
        <meta name="apple-mobile-web-app-capable" content="yes">  
        <meta name="apple-mobile-web-app-status-bar-style" content="black">  
        <meta charset="utf-8">  
        <title></title>  
        <link rel="stylesheet" href="css/cropper.min.css" />  
        <link rel="stylesheet" href="css/mui.min.css" />  
        <style>  
            #redo{  
                position: fixed;  
                bottom: 20px;  
                left :20px;  
                font-size: 30px;  
                color: #FFFFFF;  
            }  
            #undo{  
                position: fixed;  
                bottom: 20px;  
                right :20px;  
                font-size: 30px;  
                color: #FFFFFF;  
            }  
            html{  
                background: #000000;  
            }  
            .holdcenter{  
                background-color: #007AFF;  
                order:auto;  
                flex: 0 1 auto;  
                -webkit-flex: 0 1 auto;  
                align-self: auto;  
                overflow: hidden;  
            }  
            .outer-box{  
                display: flex;  
                display: -webkit-flex;  
                /*height: 100%;*/  
                /*border: 1px solid #000000;*/  
                background-color: #000000;  
                flex-direction: row;  
                flex-flow: row wrap;  
                -webkit-flex-flow: row wrap;  
                /*justify-content: flex-start;*/  
               justify-content: center;  
               align-items: center;  
            }  
        </style>  
    </head>  
    <body>  
        <header class="mui-bar mui-bar-transparent">  
          <!--<h1 id="patientId" class="mui-title">截取头像</h1>-->  
          <a id="save"  class="mui-icon mui-icon-checkmarkempty mui-pull-right" style="font-size: 3rem;color: #FFFFFF;"></a>  
        </header>  
        <div style="" class="outer-box mui-fullscreen">  
            <div style="" class="holdcenter">  
                <img style="width: 100%;" id="image" src="images/cbd.jpg">  
            </div>  
            <a id="redo" class=" mui-pull-left"><span class="mui-icon mui-icon-redo"></span></a>  
            <a id="undo" class=" mui-pull-right"><span class="mui-icon mui-icon-undo"></span></a>  
        </div>  
        <script type="text/javascript" src="js/mui.min.js" ></script>  
        <script type="text/javascript" src="js/cropper.min.js" ></script>  
        <script>  
            /**  
             * 本功能灵感来源于 crooper.js。github地址请看js文件  
             * 利用cropper.js进行图片剪裁。支持旋转。  
             * 可以直接获取剪裁后的base64。  
             * 也可以利用cropper的方法,可以获取一系列参数,借用5+API,  
             * 可以直接保存本地图片,效率非常高。  
             * 有对cropper.js熟悉的可以进一步研究修改,提供更多可用功能  
             * 理论上完全兼容android和ios系统。  
             */  
            mui.init({  
                hardwareAccelerated:true,  
            });  

            var image = document.getElementById('image');//获取图片元素  
            var cropper = null;  
            var resImg = null;      //剪切后图片base64编码资源  

            //初始化控件的方法  
            function initCropper(){  
                cropper = new Cropper(image, {  
                    //aspectRatio: 1/1,16/9,4/3,2/3,NaN(自定义)  
                    aspectRatio: NaN,   //不锁定 "剪裁框" 比例(自定义)  
                    dragMode:'crop',  
                    rotatable:true, //是否允许旋转  
                    minCropBoxWidth:0,  
                    minCropBoxHeight:0,  
                    minCanvasWidth:0,  
                    minCanvasHeight:0,  
                    minContainerWidth:200,  
                    minContainerHeight:200,  
                    cropBoxResizable: true, //是否允许 调整 剪裁框 的大小  
                    crop: function(data) {  
                     }  
                });  
            }// initCropper  end  

            //保存按钮监听  
            document.getElementById("save").addEventListener("tap",function(){  
                //传入true,获取base64字串,不传或者传入false保存本地文件,获取保存路径。  
                getImg();  
            });  
            //右旋转按钮监听  
            document.getElementById("redo").addEventListener("tap",function(){  
                cropper.rotate(90);  
                //这里的旋转角度90数据可自行定义,比方说:15,30,45。支持每次旋转1度  
                //但是考虑到5+api的旋转只支持90一个单位,所以设定每次旋转90度。  
                //有兴趣可以去cropper的范列网站https://fengyuanchen.github.io/cropperjs/自己定义旋转角度试试。  
                //但是227行的5+api旋转参数如何对应需要动脑筋。90度旋转对用户来说应该足够了。  
            });  
            //左旋转按钮监听  
            document.getElementById("undo").addEventListener("tap",function(){  
                cropper.rotate(-90);  
            });  

            //在选择或者拍摄完成后打开此裁剪页面并把图片路径传递到此页面  
            mui.plusReady(function(){  
                //imgSrc是webview的扩展参数传过来的图片路径,用io方法转换成本地绝对路径  
                image.src = plus.io.convertLocalFileSystemURL(plus.webview.currentWebview().imgSrc);  
                //image.src = "images/muwu.jpg";  

                initCropper();  //初始化cropper控件  
            });//plusReady  end  

            /**  
             * 获取图片的方法  
             * @param {Boolean} flag  
             */  
            function getImg(flag){  
                //如果flag传入true,生成base64资源     

                if(flag){  
                    resImg =  cropper.getCroppedCanvas({  
                          width: 300,  
                          height: 300  
                    }).toDataURL();  
                    //纯cropper.js的功能  
                    //resImg 就是base64字符串,可以返回给需要的页面或者上传  
                    console.log(resImg);  
                    //like is “data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAAFkCAYAAACadgZ0AAAgAElEQVR4XtS9”  
                }else{  
                //否则生成本地图片  
                    //cropper提供的方法,可以获取剪裁范围内的图片的信息,这一个方法就够了。下面的其他方法仅供参考  
                    var cropeddata = cropper.getData();               
                    //console.log(JSON.stringify(cropeddata));  
                    /* 像这样  
                     * {"x":793.6,      /左边距,像素,单位px  
                     * "y":297.59999999999997,  //上边距  
                    *   "width":2380.7999999999997,     //选中的部分图片的宽度,px,Number  
                    *   "height":2380.7999999999997,    //选中部分图片的高度,px,Number  
                    *   "rotate":0,                     //旋转度数,Number  
                    *   "scaleX":1,                     //x轴缩放比例Number  
                    *   "scaleY":1}                     //y轴缩放比例Number  
                    */  

                    //原始图片信息  
                    var sourceImgDate = cropper.getImageData();  
                    //console.log(JSON.stringify(sourceImgDate));  
                    /* 像这样  
                     * {"naturalWidth":3968,        //原始图片宽度,px,像素  
                        "naturalHeight":2976,       //原始图片高度,px  
                        "aspectRatio":1.3333333333333333,   //纵横比,高宽比  
                        "width":360,                        //在页面上的显示尺寸  
                        "height":270,  
                        "left":0,  
                        "top":0}  
                     */  

                    //获取容器(img元素)的信息  
                    var containerData = cropper.getContainerData();  
                    //console.log(JSON.stringify(containerData));  
                    /*  像这样  
                     * {"width":360,"height":276}  
                     */  

                    //剪裁框的信息  
                    var cropData = cropper.getCropBoxData();  
                    //console.log(JSON.stringify(cropData));  
                    /*  像这样  
                     * {"left":72,"top":30,  
                     *  "width":216,  
                     * "height":216}  
                     */  

                    //获取canvers的信息  
                    var canversData = cropper.getCanvasData();  
                    //console.log(JSON.stringify(canversData));  
                    /*  像这样  
                     * {"left":0,"top":3,  
                     * "width":360,  
                     * "height":270,  
                     * "naturalWidth":3968,  
                     * "naturalHeight":2976}  
                     */  

                    //接下来使用H5+的图片压缩压缩转换API来完成剪裁和压缩  
                    //http://www.html5plus.org/doc/zh_cn/zip.html  
                    //准备工作  
                    //JSON对象,图片裁剪区域的参数  
                    //注意:4个属性我们都已经通过cropper的getData()方法直接获取到了值,是不是很简单呢  
                    //直接组织数据吧  
                    var ClipImageOptions = {  
                        top:cropeddata.y ,      //(String 类型 )图片裁剪区域与原图片上边界的偏移距离  
                                    //支持像素值(如"10px")、百分比(如"10%");默认值为"0px"。 注意:如果top值超出原图片高度,则图片裁剪失败。  

                        left:cropeddata.x ,     //(Stirng 类型 )图片裁剪区域与原图片左边界的偏移距离  
                                    //支持像素值(如"10px")、百分比(如"10%");默认值为"0px"。 注意:如果left值超出原图片宽度,则图片裁剪失败。  

                        width:cropeddata.width,         //(String 类型 )图片裁剪区域的宽度  
                                    //支持像素值(如"100px")、百分比(如"50%")、自动计算(如"auto",即从left位置到图片右边界的宽度);默认值为"auto"。 注意:如果left值加width值超出原图片宽度,则使用"auto"值进行裁剪。  

                        height:cropeddata.height    //(String 类型 )图片裁剪区域的高度  
                                    //支持像素值(如"100px")、百分比(如"50%")、自动计算(如"auto",即从top位置到图片下边界的高度);默认值为"auto"。 注意:如果top值加height值超出原图片高度,则使用"auto"值进行裁剪。  
                    }  

                    //处理旋转角度,因为5+api不接受负值  
                    var rotate = 0;//默认值  
                    if(cropeddata.rotate >= 0){  
                        rotate = cropeddata.rotate;  
                    }else{  
                        switch(cropeddata.rotate){  
                            case -90:  
                                rotate = 270;  
                                break;  
                            case -180:  
                                rotate = 180;  
                                break;  
                            case -270:  
                                rotate = 90;  
                                break;  
                            default:  
                                rotate = 0;   
                        }  
                    }  

                    //获取图片格式                  
                    var format = image.src.substring(image.src.lastIndexOf(".")+1);  
                    //console.log(format);  
                    //根据日期生成图片名称  
                    var d = new Date();                   
                    var picName = d.getFullYear()+""+(d.getMonth()+1)+""+d.getDate()+""+d.getHours()+""+d.getMinutes()+""+d.getSeconds();  
                    var fullname = picName+"."+format;  
                    console.log(fullname); //完整图片名称  

                    //JSON对象,配置图片压缩转换的参数  
                    var imgOption = {src:image.src,     //原始图片路径  
                        dst: "../doc/"+fullname ,//(String 类型 )压缩转换目标图片的路径,这里保存到 私有目录doc  
                                                    //如“/sdcard/Android/data/io.dcloud.HBuilder/.HBuilder/apps/HBuilder/doc”。  
                        overwrite:true,     //覆盖生成新文件  
                        format: '',//(String 类型 )压缩转换后的图片格式,支持"jpg"、"png",如果未指定则使用源图片的格式。  
                        quality:50,//(Number 类型 )压缩图片的质量,可以自己调整  
                                        //取值范围为1-100,1表示使用最低的图片质量(转换后的图片文件最小)、100表示使用最高的图片质量(转换后的图片文件最大); 默认值为50。  
                        width:'auto',       //(String 类型 )缩放图片的宽度  
                                    //支持像素值(如"100px")、百分比(如"50%")、自动计算(如"auto",即根据height与源图高的缩放比例计算,若未设置height则使用源图高度); 默认值为"auto"。 注意:若设置了width属性值不合法(如"0px"),则不对图片进行缩放操作。  

                        height:'auto',  //(String 类型 )缩放图片的高度  
                                        //支持像素值(如"100px")、百分比(如"50%")、自动计算(如"auto",即根据width与源图宽的缩放比例计算,若未设置width则使用源图高度); 默认值为"auto"。 注意:若设置了height属性值不合法(如"0px"),则不对图片进行缩放操作。  

                        rotate:rotate,      //(Number 类型 )旋转图片的角度  
                                        //支持值:90-表示旋转90度;180-表示旋转180度;270-表示旋转270度。 注意:若设置rotate属性值不合法,则不对图片进行旋转操作。  
                        clip: ClipImageOptions          //(ClipImageOptions 类型(json对象) )裁剪图片的区域  
                                        //值参考ClipImageOptions定义,若设置clip属性值不合法,则不对图片进行裁剪操作。  
                    }  

                    //开始剪裁  
                    plus.zip.compressImage(  
                            imgOption,      //JSON对象,配置图片压缩转换的参数  
                            function(){                                                                           
                                //console.log(imgOption.dst);                         
                                //console.log("压缩成功");  
                                mui.toast("图片已保存到:"+imgOption.dst,{duration:"long"});  
                                //如果想要绝对路径  
                                var path=plus.io.convertLocalFileSystemURL(imgOption.dst);  
                                console.log(path);  
                                //后续处理  
                                //将imgOption.dst或者path传递给父页面,用来显示或者上传后台,请自行决定  
                                //mui.fire(plus.webview.currentWebview().opener(),"avart",{img:imgOption.dst});  
                            },function(error){                        
                                console.log("压缩失败");  

                            }  
                        );  

                    //如果不是存到doc目录,而是其他比较复杂的目录,比如根目录  
                    //用下面的方法。替换plus.io.PRIVATE_DOC就可以  
                    /*plus.io.requestFileSystem(plus.io.PRIVATE_DOC,function(fs){  
                        var filepath = fs.root.fullPath;  
                        //console.log(fs.root.fullPath);  
                        var directEntery = fs.root;  
                        //创建目录,其实这一段并不是必须的,  
                        //plus.zip.compressImage自己会创建文件夹  
                        //相对目录你可以在上面imgOption.dst里面直接写上相对路径"../doc"+fullname  
                        directEntery.getDirectory(  
                                filepath,  
                                {create:true,exclusive:false},  
                                function(direnter){  
                                    //如果文件夹已经存在,也会进入这里,所以就不用toast显示了  
                                    //mui.toast("创建doc文件夹成功");  
                                },function(e){  
                                    mui.toast("创建文件夹失败:"+e.message);  
                                    mui.back();  
                                }  
                        );  

                        //把目标路径更新到json对象  
                        imgOption.dst = filepath+fullname;  
                        //开始压缩图片  
                        plus.zip.compressImage(imgOption,  
                            function(){                                                                           
                                //console.log(imgOption.dst);                         
                                //console.log("压缩成功");  
                                mui.toast("图片已保存到:"+imgOption.dst,{duration:long});  
                                //将imgOption.dst传递给父页面,用来显示或者上传后台  
                            },function(error){                        
                                console.log("压缩失败");  

                        });  
                    }); */  

                }  

                //最后退出剪裁页面  
                mui.back();  
            }         

        </script>  
    </body>  
</html>
收起阅读 »

整理了一下Mdui,丰富一下Mui的样式

mui

个人觉得Mui的样式不太美观,因此我整理另一款优秀的UI框架Mdui,和Mui可以无缝对接,话不多说,直接上github地址:
https://github.com/BysunLin/Mgui

我不是代码的创造者,我只是搬运工,不过里面也加入了一些我工作中的一些积累,期望可以对入坑的同学有一点点帮助。
tips:如果能顺手加个星那就更好啦!

继续阅读 »

个人觉得Mui的样式不太美观,因此我整理另一款优秀的UI框架Mdui,和Mui可以无缝对接,话不多说,直接上github地址:
https://github.com/BysunLin/Mgui

我不是代码的创造者,我只是搬运工,不过里面也加入了一些我工作中的一些积累,期望可以对入坑的同学有一点点帮助。
tips:如果能顺手加个星那就更好啦!

收起阅读 »

android离线打包6.0以上的权限动态申请

App离线打包 权限 Android

页面调用

// android6.0以上权限申请   
function requestAndroidPremission(requestCode, func){  
    if(!permissionUtils){  
        permissionUtils = plus.android.newObject("com.build.canteen.util.PermissionUtils");  
    }  
    requestAndroidPremissionCallBack = function(requestCode){  
        if(typeof func == 'function'){  
            func(requestCode);  
        }  
    }  
    // 实现原生接口com.build.canteen.util.PermissionUtils.RequestWebViewPremissionListener对象  
    var hevent = plus.android.implements( "com.build.canteen.util.PermissionUtils$RequestWebViewPremissionListener", {  
        "requestPremissionCallBack":function(requestCode){  
            requestAndroidPremissionCallBack(requestCode)  
//          console.log( "Invoked Object’s name: "+name ); // 输出“Invoked Object’s name: Tester”  
        }  
    });  
    plus.android.invoke(permissionUtils,'setRequestWebViewPremissionListener',hevent);  
    plus.android.invoke(permissionUtils,"requestWebViewPremission",requestCode,'requestAndroidPremissionCallBack');  
}

android原生代码片段:

    // mui 动态权限申请代码  ↓↓↓↓↓↓↓↓↓↓↓↓  
    //底层隐藏的自定义Activity,重写onRequestPermissionsResult  
    private static MainActivity mActivity;  
    //由webview中的js实现此接口,用于权限申请完成后的回调webview的js函数  
    private RequestWebViewPremissionListener requestWebViewPremissionListener;  

    public static void setMainActivity(MainActivity aty){  
        mActivity = aty;  
    }  

    public void setRequestWebViewPremissionListener(RequestWebViewPremissionListener requestWebViewPremissionListener){  
        this.requestWebViewPremissionListener = requestWebViewPremissionListener;  
    }  

    public interface RequestWebViewPremissionListener{  
        void requestPremissionCallBack(int requestCode);  
    }  

    //mui调用此方法申请权限  
    public void requestWebViewPremission(int requestCode){  
        if(mActivity != null  && Build.VERSION.SDK_INT >= 23){  
            //在Activity中的onRequestPermissionsResult方法被调用  
            PermissionGrant permissionGrant = new PermissionUtils.PermissionGrant() {  
                @Override  
                public void onPermissionGranted(int requestCode) {  
                    if(requestWebViewPremissionListener!=null){  
                        requestWebViewPremissionListener.requestPremissionCallBack(requestCode);  
                    }  
                }  
            };  
            mActivity.setPermissionGrant(permissionGrant);  
            //安卓原生实现的权限申请  
            requestPermission(mActivity,requestCode,permissionGrant);  
        }else if(Build.VERSION.SDK_INT < 23){  
            if(requestWebViewPremissionListener!=null){  
                requestWebViewPremissionListener.requestPremissionCallBack(requestCode);  
            }  
        }else{  
            Log.w(TAG,"WebView  requestWebViewPremission error ,安卓运行版本:"+Build.VERSION.SDK_INT);  
        }  
    }  
    // mui 动态权限申请代码  ↑↑↑↑↑↑↑↑
写的比较粗糙,还望大神指导!
继续阅读 »

页面调用

// android6.0以上权限申请   
function requestAndroidPremission(requestCode, func){  
    if(!permissionUtils){  
        permissionUtils = plus.android.newObject("com.build.canteen.util.PermissionUtils");  
    }  
    requestAndroidPremissionCallBack = function(requestCode){  
        if(typeof func == 'function'){  
            func(requestCode);  
        }  
    }  
    // 实现原生接口com.build.canteen.util.PermissionUtils.RequestWebViewPremissionListener对象  
    var hevent = plus.android.implements( "com.build.canteen.util.PermissionUtils$RequestWebViewPremissionListener", {  
        "requestPremissionCallBack":function(requestCode){  
            requestAndroidPremissionCallBack(requestCode)  
//          console.log( "Invoked Object’s name: "+name ); // 输出“Invoked Object’s name: Tester”  
        }  
    });  
    plus.android.invoke(permissionUtils,'setRequestWebViewPremissionListener',hevent);  
    plus.android.invoke(permissionUtils,"requestWebViewPremission",requestCode,'requestAndroidPremissionCallBack');  
}

android原生代码片段:

    // mui 动态权限申请代码  ↓↓↓↓↓↓↓↓↓↓↓↓  
    //底层隐藏的自定义Activity,重写onRequestPermissionsResult  
    private static MainActivity mActivity;  
    //由webview中的js实现此接口,用于权限申请完成后的回调webview的js函数  
    private RequestWebViewPremissionListener requestWebViewPremissionListener;  

    public static void setMainActivity(MainActivity aty){  
        mActivity = aty;  
    }  

    public void setRequestWebViewPremissionListener(RequestWebViewPremissionListener requestWebViewPremissionListener){  
        this.requestWebViewPremissionListener = requestWebViewPremissionListener;  
    }  

    public interface RequestWebViewPremissionListener{  
        void requestPremissionCallBack(int requestCode);  
    }  

    //mui调用此方法申请权限  
    public void requestWebViewPremission(int requestCode){  
        if(mActivity != null  && Build.VERSION.SDK_INT >= 23){  
            //在Activity中的onRequestPermissionsResult方法被调用  
            PermissionGrant permissionGrant = new PermissionUtils.PermissionGrant() {  
                @Override  
                public void onPermissionGranted(int requestCode) {  
                    if(requestWebViewPremissionListener!=null){  
                        requestWebViewPremissionListener.requestPremissionCallBack(requestCode);  
                    }  
                }  
            };  
            mActivity.setPermissionGrant(permissionGrant);  
            //安卓原生实现的权限申请  
            requestPermission(mActivity,requestCode,permissionGrant);  
        }else if(Build.VERSION.SDK_INT < 23){  
            if(requestWebViewPremissionListener!=null){  
                requestWebViewPremissionListener.requestPremissionCallBack(requestCode);  
            }  
        }else{  
            Log.w(TAG,"WebView  requestWebViewPremission error ,安卓运行版本:"+Build.VERSION.SDK_INT);  
        }  
    }  
    // mui 动态权限申请代码  ↑↑↑↑↑↑↑↑
写的比较粗糙,还望大神指导!
收起阅读 »