zoukankan      html  css  js  c++  java
  • 关于MUI一个很实用的前端框架

    今天也是我接触mui的第一天。首先先上MUI的官网上面瞧一瞧。http://dev.dcloud.net.cn/mui/window/#closewindow我这里上的不是官网,

    我是先把他的基本能实现的功能先做了一个简单的了解。下面大家跟着我看:

    一、Mui的组件

    mui的组件都很原生比如拓展阅读,操作表,折叠面板,你需要那个组件就把那个组件拷贝下来,例如你需要折叠面板

    <ul class="mui-table-view"> 
            <li class="mui-table-view-cell mui-collapse">
                <a class="mui-navigate-right" href="#">面板1</a>
                <div class="mui-collapse-content">
                    <p>面板1子内容</p>
                </div>
            </li>
        </ul>
    还有单选框,轮播图,数字角标,消息框,卡片视图,透明状态栏,右滑,左滑,等等组件,再将你想要使用的模板复制下来,粘贴到你想要想放进去的地方即可。
    二、MUI的窗口
    MUI的窗口包括页面的初始化,创建子页面,打开新页面,打开带原声带导航栏的新页面,关闭页面,预加载等。
    不管你是打一个新页面还是创建一个新页面它里面都会夹杂着你想要的动画效果,比如下拉刷新,下拉刷新打开一个新页面。
    下面拿着页面初始化来举一个例子:
    在app开发中,若要使用HTML5+扩展api,必须等plusready事件发生后才能正常使用,mui将该事件封装成了mui.plusReady()方法,涉及到HTML5+的api,建议都写在mui.plusReady方法中。如下为打印当前页面URL的示例:

    mui.plusReady(function(){
         console.log("当前页面URL:"+plus.webview.currentWebview().getURL());
    });

    扩展阅读

    mui.init()    mui插件初始化

    mui.ready()    当DOM准备就绪时,指定一个函数来执行。

    创建子页面

    mobile app开发过程中,经常会出现共用的导航栏或者选项卡,每次打开页面都需要重新渲染,而且容易出现卡头卡尾的现象。并且此时若使用局部滚动,在android手机上会出现滚动不流畅的问题;

    mui现在提供两种解决方案:

    第一种(官方推荐):在plus环境下,使用原生titleNView以及原生tabbar来替换页面的导航栏或者选项卡。在页面打开时,渲染已经完成,让你的应用更接近原生app。具体做法:原生titleNView参考mui.openWindow示例3,原生tabbar示例参考ask教程示例

    第二种:通过双webview模式解决,此种情况适用于需要上下拉刷新的列表页面。将需要滚动的区域通过单独的webview实现,完全使用原生滚动

    具体做法则是:将目标页面分解为主页面和内容页面,主页面显示卡头卡尾区域,比如顶部导航、底部选项卡等;内容页面显示具体需要滚动的内容,然后在主页面中调用mui.init方法初始化内容页面。

    mui.init({
        subpages:[{
          url:your-subpage-url,//子页面HTML地址,支持本地地址和网络地址
          id:your-subpage-id,//子页面标志
          styles:{
            top:subpage-top-position,//子页面顶部位置
            bottom:subpage-bottom-position,//子页面底部位置
            width:subpage-width,//子页面宽度,默认为100%
            height:subpage-height,//子页面高度,默认为100%
            ......
          },
          extras:{}//额外扩展参数
        }]
      });

    参数说明:styles表示窗口属性,参考5+规范中的WebviewStyle特别注意,height和width两个属性,即使不设置,也默认按100%计算;因此若设置了top值为非"0px"的情况,

    建议同时设置bottom值,否则5+ runtime根据高度100%计算,可能会造成页面真实底部位置超出屏幕范围的情况;left、right同理。

    打开新页面

    做web app,一个无法避开的问题就是转场动画;web是基于链接构建的,从一个页面点击链接跳转到另一个页面,如果通过有刷新的打开方式,用户要面对一个空白的页面等待;如果通过无刷新的方式,用Javascript移入DOM节点(常见的SPA解决方案),会碰到很高的性能挑战:DOM节点繁多,页面太大,转场动画不流畅甚至导致浏览器崩溃; mui的解决思路是:单webview只承载单个页面的dom,减少dom层级及页面大小;页面切换使用原生动画,将最耗性能的部分交给原生实现.

    mui.openWindow({
        url:new-page-url,
        id:new-page-id,
        styles:{
          top:newpage-top-position,//新页面顶部位置
          bottom:newage-bottom-position,//新页面底部位置
          width:newpage-width,//新页面宽度,默认为100%
          height:newpage-height,//新页面高度,默认为100%
          ......
        },
        extras:{
          .....//自定义扩展参数,可以用来处理页面间传值
        },
        createNew:false,//是否重复创建同样id的webview,默认为false:不重复创建,直接显示
        show:{
          autoShow:true,//页面loaded事件发生后自动显示,默认为true
          aniShow:animationType,//页面显示动画,默认为”slide-in-right“;
          duration:animationTime//页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒;
        },
        waiting:{
          autoShow:true,//自动显示等待框,默认为true
          title:'正在加载...',//等待对话框上显示的提示内容
          options:{
            width:waiting-dialog-widht,//等待框背景区域宽度,默认根据内容自动计算合适宽度
            height:waiting-dialog-height,//等待框背景区域高度,默认根据内容自动计算合适高度
            ......
          }
      

    参数:

    • styles

      窗口参数,参考5+规范中的WebviewStyle;特别注意,height和width两个属性,即使不设置,也默认按100%计算;因此若设置了top值为非"0px"的情况,建议同时设置bottom值,否则5+ runtime根据高度100%计算,可能会造成页面真实底部位置超出屏幕范围的情况;left、right同理。

    • extras

      新窗口的额外扩展参数,可用来处理页面间传值;例如:

      var webview = mui.openWindow({
      	url:'info.html',
      	extras:{
      		name:'mui'  //扩展参数
      	}
      });
      console.log(webview.name);//输出mui字
      注意:扩展参数仅在打开新窗口时有效,若目标窗口为预加载页面,则通过mui.openWindow方法打开时传递的extras参数无效。
    • createNew

      是否重复创建相同id的webview;

      为优化性能、避免app中重复创建webview,mui v1.7.0开始增加createNew参数,默认为false;判断逻辑如下:

      • createNew参数为为true,则不判断重复,每次都新建webview;

      • createNew参数为为fasle,则先查找当前App中是否已存在同样id的webview,若存在则直接显示;否则新创建并根据show参数执行显示逻辑;

      注意:plusReady事件仅在webview首次创建时触发,使用mui.openWindow方法多次打开已存在的同样id的webview时,是不会重复触发plusReady事件的; 因此若业务写在plusReady事件中,可能会出现执行结果和预期不一致的情况;此时可通过自定义事件触发; 案例参考:mui.plusReady有时会失效;

    • show

      窗口显示控制参数,具体参数如下:

      • autoShow:目标窗口loaded事件发生后,是否自动显示,默认为true;若为false,则仅创建但不显示webview;若目标页面为预加载页面,则该参数无效;

      • aniShow表示页面显示动画,比如从右侧划入、从下侧划入等,具体可参考5+规范中的AnimationTypeShow

      • duration:显示Webview窗口动画的持续时间,单位为ms

    • waiting

      系统等待框参数

      mui框架在打开新页面时等待框的处理逻辑为:

      显示等待框-->创建目标页面webview-->目标页面loaded事件发生-->关闭等待框;

      因此,只有当新页面为新创建页面(webview)时,会显示等待框,否则若为预加载好的页面,则直接显示目标页面,不会显示等待框。waiting中的具体参数:

      • autoShow:是否自动显示等待框,默认为true;若为false,则不显示等待框;注意:若waiting框的autoShow为true,但目标页面不自动显示,则需在目标页面中通过如下代码关闭等待框:plus.nativeUI.closeWaiting();

      • title:等待框上的提示文字

      • options表示等待框显示参数,比如宽高、背景色、提示文字颜色等,具体可参考5+规范中的WaitingOption

    示例1:Hello mui中,点击首页右上角的图标,会打开关于页面,实现代码如下:

    //tap为mui封装的单击事件,可参考手势事件章节
    document.getElementById('info').addEventListener('tap', function() {
      //打开关于页面
      mui.openWindow({
        url: 'examples/info.html', 
        id:'info'
      });
    })

    因没有传入styles参数,故默认全屏显示;也没有传入show参数,故使用slide-in-right动画,新页面从右侧滑入。

    示例2:从A页面打开B页面,B页面为一个需要从服务端加载的列表页面,若在B页面loaded事件发生时就将其显示出来,因服务器数据尚未加载完毕,

    列表页面为空,用户体验不好;可通过如下方式改善用户体验(最好的用户体验应该是通过预加载的方式):第一步,B页面loaded事件发生后,不自动显示;

    //A页面中打开B页面,设置show的autoShow为false,则B页面在其loaded事件发生后,不会自动显示;
    mui.openWindow({
        url: 'B.html', 
        show:{
          autoShow:false
        }
      });

    第二步,在B页面获取列表数据后,再关闭等待框、显示B页面

    //B页面onload从服务器获取列表数据;
    window.onload = function(){
      //从服务器获取数据
      ....
      //业务数据获取完毕,并已插入当前页面DOM;
      //注意:若为ajax请求,则需将如下代码放在处理完ajax响应数据之后;
      mui.plusReady(function(){
        //关闭等待框
        plus.nativeUI.closeWaiting();
        //显示当前页面
        mui.currentWebview.show();
      });
    }
    三、MUI的事件
    mui的事件包括事件绑定,事件取消,事件触发,手势事件。自定义事件。

    事件绑定

    除了可以使用addEventListener()方法监听某个特定元素上的事件外, 也可以使用.on()方法实现批量元素的事件绑定。

    .on( event , selector , handler )

    • event
      Type: String
      需监听的事件名称,例如:'tap'
    • selector
      Type: String
      选择器
    • handler
      Type: FunctionEvent event )
      事件触发时的回调函数,通过回调中的event参数可以获得事件详情

    示例

    点击新闻列表,获取当前列表项的id,并将该id传给新闻详情页面,然后打开新闻详情页面

    mui(".mui-table-view").on('tap','.mui-table-view-cell',function(){
      //获取id
      var id = this.getAttribute("id");
      //传值给详情页面,通知加载新数据
      mui.fire(detail,'getDetail',{id:id});
      //打开新闻详情
      mui.openWindow({
        id:'detail',
        url:'detail.html'
      });
    }) 

    事件取消

    使用on()方法绑定事件后,若希望取消绑定,则可以使用off()方法。 off()方法根据传入参数的不同,有不同的实现逻辑。

    • version added: 2.0.0.off( event , selector , handler )

      • event
        Type: String
        需取消绑定的事件名称,例如:'tap'
      • selector
        Type: String
        选择器
      • handler
        Type: Function
        之前绑定到该元素上的事件函数,不支持匿名函数
    • version added: 2.0.0.off( event , selector)

      • event
        Type: String
        需取消绑定的事件名称,例如:'tap'
      • selector
        Type: String
        选择器
    • version added: 2.2.0.off( event )

      • event
        Type: String
        需取消绑定的事件名称,例如:'tap'
    • version added: 2.2.0.off( )

      • 空参数,删除该元素上所有事件

    示例

    off(event,selector,handle)适用于取消对应选择器上特定事件所执行的特定回调,例如:

    //点击li时,执行foo_1函数
    mui("#list").on("tap","li",foo_1);
    //点击li时,执行foo_2函数
    mui("#list").on("tap","li",foo_2);
    
    function foo_1(){
      console.log("foo_1 execute");
    }
    
    function foo_2(){
      console.log("foo_2 execute");
    }
    //点击li时,不再执行foo_1函数,但会继续执行foo_2函数
    mui("#list").off("tap","li",foo_1);

    off(event,selector)适用于取消对应选择器上特定事件的所有回调,例如:

    //点击li时,执行foo_1函数
    mui("#list").on("tap","li",foo_1);
    //点击li时,执行foo_2函数
    mui("#list").on("tap","li",foo_2);
    
    function foo_1(){
      console.log("foo_1 execute");
    }
    
    function foo_2(){
      console.log("foo_2 execute");
    }
    //点击li时,foo_2、foo_2两个函数均不再执行
    mui("#list").off("tap","li");

    off(event)适用于取消当前元素上绑定的特定事件的所有回调,例如:

    //点击li时,执行foo_1函数
    mui("#list").on("tap","li",foo_1);
    //点击p时,执行foo_3函数
    mui("#list").on("tap","p",foo_3);
    
    function foo_1(){
      console.log("foo_1 execute");
    }
    
    function foo_3(){
      console.log("foo_3 execute");
    }
    //点击li时,不再执行foo_1函数;点击p时,也不再执行foo_3函数
    mui("#list"

    off()适用于取消当前元素上绑定的所有事件回调,例如:

    //点击li时,执行foo_1函数
    mui("#list").on("tap","li",foo_1);
    //双击li时,执行foo_4函数
    mui("#list").on("doubletap","li",foo_4);
    //点击p时,执行foo_3函数
    mui("#list").on("tap","p",foo_3);
    
    function foo_1(){
      console.log("foo_1 execute");
    }
    
    function foo_3(){
      console.log("foo_3 execute");
    }
    
    function foo_4(){
      console.log("foo_4 execute");
    }
    //点击li时,不再执行foo_1函数;点击p时,也不再执行foo_3函数;双击li时,也不再执行foo_4函数;
    mui("#list").off();

    事件触发

    使用mui.trigger()方法可以动态触发特定DOM元素上的事件。

    • .trigger( element , event , data )

      • element
        Type: Element
        触发事件的DOM元素
      • event
        Type: String
        事件名字,例如:'tap'、'swipeleft'
      • data
        Type: Object
        需要传递给事件的业务参数

    示例

    自动触发按钮的点击事件:

    var btn = document.getElementById("submit");
    //监听点击事件
    btn.addEventListener("tap",function () {
      console.log("tap event trigger");
    });
    //触发submit按钮的点击事件
    mui.trigger(btn,'tap');

    部分mui控件监听的事件无法通过mui.trigger触发

    比如无法实现自动触发mui返回图标,实现关闭当前页面的功能,该部分逻辑正在优化中

    手势事件

    在开发移动端的应用时,会用到很多的手势操作,比如滑动、长按等,为了方便开放者快速集成这些手势,mui内置了常用的手势事件,目前支持的手势事件见如下列表:

    分类参数描述
    点击 tap 单击屏幕
    doubletap 双击屏幕
    长按 longtap 长按屏幕
    hold 按住屏幕
    release 离开屏幕
    滑动 swipeleft 向左滑动
    swiperight 向右滑动
    swipeup 向上滑动
    swipedown 向下滑动
    拖动 dragstart 开始拖动
    drag 拖动中
    dragend 拖动结束

    手势事件配置

    根据使用频率,mui默认会监听部分手势事件,如点击、滑动事件;为了开发出更高性能的moble App,mui支持用户根据实际业务需求,通过mui.init方法中的gestureConfig参数,配置具体需要监听的手势事件,。

     
    mui.init({
      gestureConfig:{
       tap: true, //默认为true
       doubletap: true, //默认为false
       longtap: true, //默认为false
       swipe: true, //默认为true
       drag: true, //默认为true
       hold:false,//默认为false,不监听
       release:false//默认为false,不监听
      }
    });

    注意:dragstart、drag、dragend共用drag开关,swipeleft、swiperight、swipeup、swipedown共用swipe开关

    事件监听

    单个元素上的事件监听,直接使用addEventListener()即可,如下:

     elem.addEventListener("swipeleft",function(){
         console.log("你正在向左滑动");
    });

    若多个元素执行相同逻辑,则建议使用事件绑定(on())

    自定义事件

    在App开发中,经常会遇到页面间传值的需求,比如从新闻列表页进入详情页,需要将新闻id传递过去; Html5Plus规范设计了evalJS方法来解决该问题; 但evalJS方法仅接收字符串参数,涉及多个参数时,需要开发人员手动拼字符串; 为简化开发,mui框架在evalJS方法的基础上,封装了自定义事件,通过自定义事件,用户可以轻松实现多webview间数据传递。

    仅能在5+ App及流应用中使用

    因为是多webview之间传值,故无法在手机浏览器、微信中使用;

    监听自定义事件

    添加自定义事件监听操作和标准js事件监听类似,可直接通过window对象添加,如下:

    window.addEventListener('customEvent',function(event){
      //通过event.detail可获得传递过来的参数内容
      ....
    });

    触发自定义事件

    通过mui.fire()方法可触发目标窗口的自定义事件:

    • .fire( target , event , data )

      • target
        需传值的目标webview
      • event
        Type: String
        自定义事件名称
      • data
        Type: JSON
        json格式的数据

    目标webview必须触发loaded事件后才能使用自定义事件

    若新创建一个webview,不等该webview的loaded事件发生,就立即使用webview.evalJS()或mui.fire(webview,'eventName',{}),则可能无效;案例参考:这里

    示例

    假设如下场景:从新闻列表页面进入新闻详情页面,新闻详情页面为共用页面,通过传递新闻ID通知详情页面需要显示具体哪个新闻,详情页面再动态向服务器请求数据,mui要实现类似需求可通过如下步骤实现:

    • 在列表页面中预加载详情页面(假设为detail.html)
    • 列表页面在点击新闻标题时,首先,获得该新闻id,触发详情页面的newsId事件,并将新闻id作为事件参数传递过去;然后再打开详情页面;
    • 详情页面监听newsId自定义事件

    列表页面代码如下:

    //初始化预加载详情页面
    mui.init({
      preloadPages:[{
        id:'detail.html',
        url:'detail.html'           
      }
      ]
    });
    
    var detailPage = null;
    //添加列表项的点击事件
    mui('.mui-content').on('tap', 'a', function(e) {
      var id = this.getAttribute('id');
      //获得详情页面
      if(!detailPage){
        detailPage = plus.webview.getWebviewById('detail.html');
      }
      //触发详情页面的newsId事件
      mui.fire(detailPage,'newsId',{
        id:id
      });
    //打开详情页面          
      mui.openWindow({
        id:'detail.html'
      });
    });  

    详情页面代码如下:

    //添加newId自定义事件监听
    window.addEventListener('newsId',function(event){
      //获得事件参数
      var id = event.detail.id;
      //根据id向服务器请求新闻详情
      .....
    });
    四、MUI的utils(工具)
    mui的工具和jq很像但是也是有区别的。

    init

    mui框架将很多功能配置都集中在mui.init方法中,要使用某项功能,只需要在mui.init方法中完成对应参数配置即可,目前支持在mui.init方法中配置的功能包括:创建子页面关闭页面手势事件配置预加载下拉刷新上拉加载设置系统状态栏背景颜色

    mui需要在页面加载时初始化很多基础控件,如监听返回键,因此务必在每个页面中调用

    以下各配置模块在其对应文档中有详细阐述,请点击链接查看,这里只列出所有可配置项

    mui.init({
    //子页面
    	subpages: [{
    		//...
    	}],
    //预加载
    	 preloadPages:[
    	    //...
     	 ],
    //下拉刷新、上拉加载
     	pullRefresh : {
    	   //...
         	},
    //手势配置
     	 gestureConfig:{
    	   //...
    	},
    //侧滑关闭
    	swipeBack:true, //Boolean(默认false)启用右滑关闭功能
    	
    //监听Android手机的back、menu按键
    	keyEventBind: {
    		backbutton: false,  //Boolean(默认true)关闭back按键监听
    		menubutton: false   //Boolean(默认true)关闭menu按键监听
    	},
    //处理窗口关闭前的业务
    	beforeback: function() {
    		//... //窗口关闭前处理其他业务详情点击 ↑ "关闭页面"链接查看
    	},
    //设置状态栏颜色
    	statusBarBackground: '#9defbcg', //设置状态栏颜色,仅iOS可用
    	preloadLimit:5//预加载窗口数量限制(一旦超出,先进先出)默认不限制
    })
    		

    以上各配置模块在其对应文档中有详细阐述,请点击链接查看,以下只补充单独配置项

    通过statusBarBackground:rgb 属性设置状态栏颜色(iOS7.0+、安卓不支持)格式为#RRGGBB。

    mui.init({
    	statusBarBackground: '#9defbcg',
    })

    mui默认会监听Android手机的物理按键(back&menu),若不希望自动处理按键可通过以下方式关闭

    mui.init({
    	//监听Android手机的back、menu按键
    	keyEventBind: {
    		backbutton: true,  //Boolean(默认true)关闭back按键监听
    		menubutton: true   //Boolean(默认true)关闭menu按键监听
    	},
    })

    扩展阅读

    代码块激活字符:    
    minit

    mui()

    mui使用css选择器获取HTML元素,返回mui对象数组。
    mui("p"):选取所有<p>元素
    mui("p.title"):选取所有包含.title类的<p>元素

    若要将mui对象转化成dom对象,可使用如下方法(类似jquery对象转成dom对象):

    //obj1是mui对象
    var obj1 = mui("#title");
    //obj2是dom对象
    var obj2 = obj1[0]; 

    MUI框架的定位是“最接近原生体验的移动App的UI框架”, 因此和jQuery有所区别,很少为简化DOM操作而封装API,具体可参考MUI产品概述; 该函数的设计目的,更多是为了配合MUI插件使用,比如图片轮播、下拉刷新、区域滚动等,如下为详细示例:

    示例1:跳转到图片轮播的第二张图片

    mui('.mui-slider').slider().gotoItem(1);

    示例2:重新开启上拉加载

    mui('#pullup-container').pullRefresh().refresh(true);

    扩展阅读

    代码块激活字符:    
    mmui

    each()

    each既是一个类方法,同时也是一个对象方法,两个方法适用场景不同;换言之,你可以使用mui.each()去遍历数组或json对象,也可以使用mui(selector).each()去遍历DOM结构。

    • mui.each( obj , handler )

      • obj
        Type: Array||JSONObj
        需遍历的对象或数组;若为对象,仅遍历对象根节点下的key
      • handler
        Type: FunctionInteger||String index,Anything element)
        为每个元素执行的回调函数;其中,index表示当前元素的下标或key,element表示当前匹配元素
    • mui(selector).each( handler )

      • handler
        Type: FunctionInteger index,Element element)
        为每个匹配元素执行的回调函数;其中,index表示当前元素在匹配元素中的位置(下标,从0开始),element表示当前匹配元素,可用this关键字代替

    示例1

    输出当前数组中每个元素的平方

    var array = [1,2,3]
    mui.each(array,function(index,item){
      console.log(item*item);
    }) 

    示例2

    当前页面中有三个字段,如下:

    <div class="mui-input-group">
      <div class="mui-input-row">
        <label>字段1:</label>
        <input type="text" class="mui-input-clear" id="col1" placeholder="请输入">
      </div>
      <div class="mui-input-row">
        <label>字段2:</label>
        <input type="text" class="mui-input-clear" id="col2" placeholder="请输入">
      </div>
      <div class="mui-input-row">
        <label>字段3:</label>
        <input type="text" class="mui-input-clear" id="col3" placeholder="请输入">
      </div>
    </div>

    提交时校验三个字段均不能为空,若为空则提醒并终止业务逻辑运行,使用each()方法循环校验,如下:

    var check = true;
    mui(".mui-input-group input").each(function () {
      //若当前input为空,则alert提醒
      if(!this.value||trim(this.value)==""){
        var label = this.previousElementSibling;
        mui.alert(label.innerText+"不允许为空");
        check = false;
        return false;
      }
    });
    //校验通过,继续执行业务逻辑
    if(check){
      //.....
    }

    扩展阅读

    代码块激活字符:    
    meach
    mmeach(遍历DOM)

    extend()

    将两个对象合并成一个对象。

    • .extend( target , object1 [, objectN] )

      • target
        Type: Object
        需合并的目标对象
      • object1
        Type: Object
        需合并的对象
      • objectN
        Type: Object
        需合并的对象
    • .extend( deep , target , object1 [, objectN] )

      • deep
        Type: Boolean
        若为true,则递归合并
      • target
        Type: Object
        需合并的目标对象
      • object1
        Type: Object
        需合并的对象
      • objectN
        Type: Object
        需合并的对象

    示例

    var target = {
      company:"dcloud",
      product:{
        mui:"小巧、高效"
      }
    } 
    var obj1 = {
      city:"beijing",
      product:{
        HBuilder:"飞一样的编码"
      }
    }
    mui.extend(target,obj1);
    //输出:{"company":"dcloud","product":{"HBuilder":"飞一样的编码"},"city":"beijing"}
    console.log(JSON.stringify(target));

    从如上输出可以看到,product节点下的mui被替换成了HBuilder,因为默认仅合并对象根节点下的key、value;如果想深度合并,则可以传入deep参数,如下:

    var target = {
      company:"dcloud",
      product:{
        mui:"小巧、高效"
      }
    } 
    var obj1 = {
      city:"beijing",
      product:{
        HBuilder:"飞一样的编码"
      }
    }
    //支持深度合并
    mui.extend(true,target,obj1);
    //输出:{"company":"dcloud","product":{"mui":"小巧、高效","HBuilder":"飞一样的编码"},"city":"beijing"}
    console.log(JSON.stringify(target));

    扩展阅读

    代码块激活字符:    
    mextend

    later()

    setTimeOut封装

    • .later( func , delay [, context, data] )

      • func
        Type: Function
        delay毫秒后要执行的函数
      • delay
        Type: Int
        延迟的毫秒数
      • context
        Type: Object
        上下文

    扩展阅读

    代码块激活字符:    
    mlater

    scrollTo()

    滚动窗口屏幕到指定位置,该方法是对window.scrollTo()方法在手机端的增强实现,可设定滚动动画时间及滚动结束后的回调函数;鉴于手机屏幕大小,该方法仅可实现屏幕纵向滚动。

    • .scrollTo( ypos [, duration] [, handler] )

      • ypos
        Type: Integer
        要在窗口文档显示区左上角显示的文档的 y 坐标
      • duration
        Type: Integer
        滚动时间周期,单位是毫秒
      • handler
        Type: Function
        滚动结束后执行的回调函数

    示例

    1秒钟之内滚动到页面顶部

    mui.scrollTo(0,1000);

    扩展阅读

    代码块激活字符:    
    mscrollto

    os

    我们经常会有通过navigator.userAgent判断当前运行环境的需求,mui对此进行了封装,通过调用mui.os.XXX即可

    • plus(可以访问的参数为:)

      • .plus
        返回是否在 5+ App(包括流应用)运行
        .stream
        返回是否为流应用
    • Android(可以访问的参数为:)

      • .android
        返回是否为安卓手机
        .version
        安卓版本号
        .isBadAndroid
        android非Chrome环境
    • iOS(可以访问的参数为:)

      • .ios
        返回是否为苹果设备
        .version
        返回手机版本号
        .iphone
        返回是否为苹果手机
        .ipad
        返回是否为ipad
    • Wechat(可以访问的参数为:)

      • .wechat
        返回是否在微信中运行

    示例

    检测是否为iOS或安卓系统版本是否小于4.4

     if(mui.os.ios||(mui.os.android&&parseFloat(mui.os.version)<4.4)){
       //...
     } 

    工具的使用和一般的jq调用很类似也就是方法的区别,可以也是可以很容易就上手的。
    五、MUI的AJAX

    Ajax

    mui框架基于htm5plus的XMLHttpRequest,封装了常用的Ajax函数,支持GET、POST请求方式,支持返回json、xml、html、text、script数据类型; 本着极简的设计原则,mui提供了mui.ajax方法,并在mui.ajax方法基础上,进一步简化出最常用的mui.get()、mui.getJSON()、mui.post()三个方法。

    • mui.ajax( url[, settings])

      • url
        Type: String
        请求发送的目标地址
      • settings
        key/value格式的json对象,用来配置ajax请求参数,支持的完整参数参考如下mui.ajax([settings])方法
    • mui.ajax([settings])

      • settings
        key/value格式的json对象,用来配置ajax请求参数,支持的详细参数如下:
        • async
          Type: Boolean
          发送同步请求
        • crossDomain    *5+ only
          Type: Boolean
          强制使用5+跨域
        • data
          发送到服务器的业务数据
        • dataType
          Type: String
          预期服务器返回的数据类型;如果不指定,mui将自动根据HTTP包的MIME头信息自动判断;支持设置的dataType可选值:
          • "xml": 返回XML文档
          • "html": 返回纯文本HTML信息;
          • "script": 返回纯文本JavaScript代码
          • "json": 返回JSON数据
          • "text": 返回纯文本字符串
        • error
          Type: Functon(XMLHttpRequest xhr,String type,String errorThrown)
          请求失败时触发的回调函数,该函数接收三个参数:
          • xhr:xhr实例对象
          • type:错误描述,可取值:"timeout", "error", "abort", "parsererror"、"null"
          • errorThrown:可捕获的异常对象
        • success
          Type: Functon(Anything data,String textStatus,XMLHttpRequest xhr)
          请求成功时触发的回调函数,该函数接收三个参数:
          • data:服务器返回的响应数据,类型可以是json对象、xml对象、字符串等;
          • textStatus:状态描述,默认值为'success'
          • xhr:xhr实例对象
        • timeout
          Type: Number
          请求超时时间(毫秒),默认值为0,表示永不超时;若超过设置的超时时间(非0的情况),依然未收到服务器响应,则触发error回调
        • type
          Type: String
          请求方式,目前仅支持'GET'和'POST',默认为'GET'方式
        • headers
          Type: Json
          指定HTTP请求的Header
          headers:{'Content-Type':'application/json'}	              
        • processData
          Type: Boolean
          为了匹配默认的content-type("application/x-www-form-urlencoded")
          mui默认会将data参数中传入的非字符串类型的数据转变为key1=value&key2=value2格式的查询串;
          如果业务需要,希望发送其它格式的数据(比如Document对象),可以设置processDatafalse

    代码示例:如下为通过post方式向某服务器发送鉴权登录的代码片段

    mui.ajax('http://server-name/login.php',{
    	data:{
    		username:'username',
    		password:'password'
    	},
    	dataType:'json',//服务器返回json格式数据
    	type:'post',//HTTP请求类型
    	timeout:10000,//超时时间设置为10秒;
    	headers:{'Content-Type':'application/json'},	              
    	success:function(data){
    		//服务器返回响应,根据响应结果,分析是否登录成功;
    		...
    	},
    	error:function(xhr,type,errorThrown){
    		//异常处理;
    		console.log(type);
    	}
    });

    mui.post()方法是对mui.ajax()的一个简化方法,直接使用POST请求方式向服务器发送数据、且不处理timeout和异常(若需处理异常及超时,请使用mui.ajax()方法),使用方法: mui.post(url[,data][,success][,dataType]),如上登录鉴权代码换成mui.post()后,代码更为简洁,如下:

    mui.post('http://server-name/login.php',{
    		username:'username',
    		password:'password'
    	},function(data){
    		//服务器返回响应,根据响应结果,分析是否登录成功;
    		...
    	},'json'
    );

    mui.get()方法和mui.post()方法类似,只不过是直接使用GET请求方式向服务器发送数据、且不处理timeout和异常(若需处理异常及超时,请使用mui.ajax()方法),使用方法: mui.get(url[,data][,success][,dataType]),如下为获得某服务器新闻列表的代码片段,服务器以json格式返回数据列表

    mui.get('http://server-name/list.php',{category:'news'},function(data){
    		//获得服务器响应
    		...
    	},'json'
    );

    如上mui.get()方法和如下mui.ajax()方法效果是一致的:

    mui.ajax('http://server-name/list.php',{
    	data:{
    		category:'news'
    	},
    	dataType:'json',//服务器返回json格式数据
    	type:'get',//HTTP请求类型
    	success:function(data){
    		//获得服务器响应
    		...
    	}
    });

    mui.getJSON()方法是在mui.get()方法基础上的更进一步简化,限定返回json格式的数据,其它参数和mui.get()方法一致,使用方法: mui.get(url[,data][,success]),如上获得新闻列表的代码换成mui.getJSON()方法后,更为简洁,如下:

    mui.getJSON('http://server-name/list.php',{category:'news'},function(data){
    		//获得服务器响应
    		...
    	}
    );
    六、MUI的下拉刷新

    概述

    为实现下拉刷新功能,大多数 H5 框架都是通过 DIV 模拟下拉回弹动画,在低端 android 手机上,DIV 动画经常出现卡顿现象(特别是图文列表的情况); mui 通过使用原生 webview 下拉刷新解决这个 DIV 动画的卡顿问题,并且拖动效果更加流畅;

    这里提供两种模式的下拉刷新,以适用不同场景:

    单 webview 模式

    • 效果展示:
    • 动画原理:

      下拉刷新时,触发的是原生下拉刷新控件,而整个webview位置不会发生变化,所以不会在拖动过程中发生DOM重绘,当控件拖动到一定位置触发动态加载数据以及刷新操作。此模式下拉刷新,相比双webview 模式,不创建额外 webview,性能更优。

    • 使用方法:

      mui 初始化时设置pullRefresh各项参数,与双 webview 模式的子页面设置是一样的。

      说明:
      1. DOM结构无特殊要求,只需要指定一个下拉刷新容器标识即可
      mui.init({
        pullRefresh : {
          container:"#refreshContainer",//下拉刷新容器标识,querySelector能定位的css选择器均可,比如:id、.class等
          down : {
            style:'circle',//必选,下拉刷新样式,目前支持原生5+ ‘circle’ 样式
            color:'#2BD009', //可选,默认“#2BD009” 下拉刷新控件颜色
            height:'50px',//可选,默认50px.下拉刷新控件的高度,
            range:'100px', //可选 默认100px,控件可下拉拖拽的范围
            offset:'0px', //可选 默认0px,下拉刷新控件的起始位置
            auto: true,//可选,默认false.首次加载自动上拉刷新一次
            callback :pullfresh-function //必选,刷新函数,根据具体业务来编写,比如通过ajax从服务器获取新数据;
          }
        }
      });
    • 模式说明:
      • 优点:
        • 性能更优,体现在两点:
          1. 相比双webview,不创建额外子 webview 性能消耗更少
          2. 下拉拖动过程中不会发生重绘,也减少了性能消耗
      • 缺点:
        • 目前仅支持‘cricle’样式以及该样式的颜色自定义

    双 webview 模式

    • 效果展示:
    • 动画原理:

      使用双 webview 模式的下拉刷新,创建一个子 webview 添加列表;拖动时,拖动的是一个完整的 webview,避免了类似 DIV 拖动流畅度不好的问题,回弹动画使用原生动画;在 iOS 平台,H5 的动画已经比较流畅,故依然使用 H5 方案。两个平台实现虽有差异,但 mui 经过封装,可使用一套代码实现下拉刷新。

    • 使用方法:

      主页面内容比较简单,只需要创建子页面即可:

      mui.init({
          subpages:[{
            url:pullrefresh-subpage-url,//下拉刷新内容页面地址
            id:pullrefresh-subpage-id,//内容页面标志
            styles:{
              top:subpage-top-position,//内容页面顶部位置,需根据实际页面布局计算,若使用标准mui导航,顶部默认为48px;
              .....//其它参数定义
            }
          }]
      });
                

      iOS平台的下拉刷新,使用的是 mui 封装的区域滚动组件, 为保证两个平台的 DOM 结构一致,内容页面需统一按照如下 DOM 结构构建:

      <!--下拉刷新容器-->
      <div id="refreshContainer" class="mui-content mui-scroll-wrapper">
        <div class="mui-scroll">
          <!--数据列表-->
          <ul class="mui-table-view mui-table-view-chevron">
            
          </ul>
        </div>
      </div>

      其次,通过 mui.init 方法中 pullRefresh 参数配置下拉刷新各项参数,如下:

      mui.init({
        pullRefresh : {
          container:"#refreshContainer",//下拉刷新容器标识,querySelector能定位的css选择器均可,比如:id、.class等
          down : {
            height:50,//可选,默认50.触发下拉刷新拖动距离,
            auto: true,//可选,默认false.首次加载自动下拉刷新一次
            contentdown : "下拉可以刷新",//可选,在下拉可刷新状态时,下拉刷新控件上显示的标题内容
            contentover : "释放立即刷新",//可选,在释放可刷新状态时,下拉刷新控件上显示的标题内容
            contentrefresh : "正在刷新...",//可选,正在刷新状态时,下拉刷新控件上显示的标题内容
            callback :pullfresh-function //必选,刷新函数,根据具体业务来编写,比如通过ajax从服务器获取新数据;
          }
        }
      });
    • 模式说明:
    • 滚动到特定位置

      下拉刷新组件滚动到特定位置的方法类似区域滚动组件

      目前仅支持 双 webview 模式

      • scrollTo( xpos , ypos [, duration] )

        • xpos
          Type: Integer
          要在窗口文档显示区左上角显示的文档的 x 坐标
        • ypos
          Type: Integer
          要在窗口文档显示区左上角显示的文档的 y 坐标
        • duration
          Type: Integer
          滚动时间周期,单位是毫秒

      示例:在 hello mui 下拉刷新示例中,实现了双击标题栏,让列表快速回滚到顶部的功能;代码如下:

      var contentWebview = null;
      //监听标题栏的双击事件
      document.querySelector('header').addEventListener('doubletap',function () {
        if(contentWebview==null){
          contentWebview = plus.webview.currentWebview().children()[0];
        }
        //内容区滚动到顶部
        contentWebview.evalJS("mui('#pullrefresh').pullRefresh().scrollTo(0,0,100)");
      });
    • 更改下拉刷新文字位置

      *可以解决修改下拉刷新子页面默认top值后,下拉刷新提示框位置异常问题

      根据实际需求在父页面给mui-content设置top属性

      目前仅支持 双 webview 模式

      .mui-bar-nav ~ .mui-content .mui-pull-top-pocket{
        top: 180px !important;
      }

    自动触发下拉刷新

    mui 支持设置首次加载时自动触发一次下拉刷新,配置如下auto参数为:true即可,上拉加载同样支持此配置

    mui.init({
      pullRefresh : {
        container:"#refreshContainer",//下拉刷新容器标识,querySelector能定位的css选择器均可,比如:id、.class等
        down : {
          auto: true,//可选,默认false.首次加载自动下拉刷新一次
        },
        up : {
          auto: true //可选,默认false.首次加载自动上拉加载一次
        }
      }
    });

    下拉刷新结束

    两种模式在下拉刷新过程中,当获取新数据后,都需要执行 endPulldown 方法, 该方法的作用是关闭“正在刷新”的样式提示,内容区域回滚顶部位置,如下:

    function pullfresh-function() {
         //业务逻辑代码,比如通过ajax从服务器获取新数据;
         ......
         //注意,加载完新数据后,必须执行如下代码,注意:若为ajax请求,则需将如下代码放置在处理完ajax响应数据之后
         //没有更多内容了,endPulldown 传入true, 不再执行下拉刷新
         mui('#refreshContainer').pullRefresh().endPulldown();
    }

    七、MUI的上拉加载

    概述

    mui的上拉加载和下拉刷新类似,都属于pullRefresh插件,使用过程如下:

    • 1、页面滚动到底,显示“正在加载...”提示(mui框架提供)
    • 2、执行加载业务数据逻辑(开发者提供)
    • 3、加载完毕,隐藏"正在加载"提示(mui框架提供)
    开发者只需关心业务逻辑,实现加载更多数据即可。

    初始化

    初始化方法类似下拉刷新,通过mui.init方法中pullRefresh参数配置上拉加载各项参数,如下:

    mui.init({
      pullRefresh : {
        container:refreshContainer,//待刷新区域标识,querySelector能定位的css选择器均可,比如:id、.class等
        up : {
          height:50,//可选.默认50.触发上拉加载拖动距离
          auto:true,//可选,默认false.自动上拉加载一次
          contentrefresh : "正在加载...",//可选,正在加载状态时,上拉加载控件上显示的标题内容
          contentnomore:'没有更多数据了',//可选,请求完毕若没有更多数据时显示的提醒内容;
          callback :pullfresh-function //必选,刷新函数,根据具体业务来编写,比如通过ajax从服务器获取新数据;
        }
      }
    });

    结束上拉加载

    加载完新数据后,需要执行endPullupToRefresh()方法,结束转雪花进度条的“正在加载...”过程

    • .endPullupToRefresh( nomore )

      • nomore
        Type: Boolean
        是否还有更多数据;若还有更多数据,则传入false; 否则传入true,之后滚动条滚动到底时,将不再显示“上拉显示更多”的提示语,而显示“没有更多数据了”的提示语;

    示例:

    function pullfresh-function() {
         //业务逻辑代码,比如通过ajax从服务器获取新数据;
         ......
         //注意:
         //1、加载完新数据后,必须执行如下代码,true表示没有更多数据了:
         //2、若为ajax请求,则需将如下代码放置在处理完ajax响应数据之后
         this.endPullupToRefresh(true|false);
    }

    重置上拉加载

    若部分业务中,有重新触发上拉加载的需求(比如当前类别已无更多数据,但切换到另外一个类别后,应支持继续上拉加载),此时调用.refresh(true)方法,可重置上拉加载控件,如下代码:

    //pullup-container为在mui.init方法中配置的pullRefresh节点中的container参数;
    //注意:refresh()中需传入true
    mui('#pullup-container').pullRefresh().refresh(true);

    禁用上拉刷新

    在部分场景下希望禁用上拉加载,比如在列表数据过少时,不想显示“上拉显示更多”、“没有更多数据”的提示语,开发者可以通过调用disablePullupToRefresh()方法实现类似需求,代码如下:

    //pullup-container为在mui.init方法中配置的pullRefresh节点中的container参数;
    mui('#pullup-container').pullRefresh().disablePullupToRefresh();

    启用上拉刷新

    使用disablePullupToRefresh()方法禁用上拉加载后,可通过enablePullupToRefresh()方法再次启用上拉加载,代码如下:

    //pullup-container为在mui.init方法中配置的pullRefresh节点中的container参数;
    mui('#pullup-container').pullRefresh().enablePullupToRefresh();

    八、MUI的代码块
    MUI的代码块有js代码块,有html的代码块详情看看我发给你们的链接。
    下面我们进入开发阶段,第一步可以上官网拷贝下来一个demo,打开HBuilder新建一个移动APP项目,选择MUI框架,粘贴你的代码运行即可。












  • 相关阅读:
    Quora 用了哪些技术(转)
    Instagram的技术探索2(转)
    Sharding & IDs at Instagram(转)
    2010“架构师接龙”问答--杨卫华VS赵劼(转)
    架构师接龙 汇总(转)
    如何成为一名软件架构师(转)
    网站架构资料集(转)
    技术好重要吗?
    洞洞那么大-悲伤那么小
    教你玩转XSS漏洞
  • 原文地址:https://www.cnblogs.com/490889763-qq/p/10818326.html
Copyright © 2011-2022 走看看