mui 日期选择器picker隐藏

我的需求是:在列表页,可以按照时间进行搜索,并且需要实现下拉刷新,上拉加载的效果。

我是用双webview写的。父页面是搜索条件,子页面是列表。

第一个问题,在父页面不显示日期选择器,因为子页面的层级比父页面高,子页面遮盖了弹出的选择器。搜索了一下,没有发现简单好用的解决方法,综合几个答案,最终决定在子页面写选择器,在父页面触发子页面的自定义事件,弹出选择器。(一步一步贴代码)

父页面(dealer-main.html),点击input时的事件:

var list = plus.webview.getWebviewById("dealer.html");
mui.fire(list,"showPicker",{})
list.show();

子页面(dealer.html)

window.addEventListener("showPicker",function(event){
    var params = { "type": "date"};
    var dtPicker = new mui.DtPicker(params); 
    dtPicker.show(function (res) {
      // 选择日期之后,将值返回到父页面,触发父页面的自定义事件 backPicker
        var list = plus.webview.getWebviewById("dealer-main.html");
        mui.fire(list,"backPicker",{
        type:event.detail.type,
        value:res.text
     })
    list.show();
  })
})

父页面自定义事件(backPicker)

window.addEventListener("backPicker",function(event){
        //赋值
    vm.$data.StartTime = event.detail.value;
})

这样写出现的第一个问题是父页面的选择器可以多次点击,每次都会触发子页面的showPicker事件,导致弹出一堆选择器框,自然是不行的。
我想到的解决方法是,在父页面定义一个变量n,值为数值0,每次点击input,这个数字都加1,并且作为参数传给子页面。在子页面判断如果n>=2,return,不弹出选择器,因为n大于等于2的情况就是多次点击父页面的input了,并且在父页面的backPicker事件里面重新给n赋值为0。暂且解决这个问题,但是会出现新问题,点击选择器的取消按钮,或者安卓(我暂时只用了安卓)的物理返回键,或者选择器的mask的时候,选择器隐藏掉,但是再次点击父页面的input,无法触发子页面的showPicker事件,很简单,n>=2了。然而,比较令我开心的是,我发现不管是点击选择器的取消,还是安卓的物理返回键,还是选择器的mask,其根本都是触发mui.picker.js的hide事件,那我觉得此时只能重写hide方法了。然而,在重写hide方法之前先说另外一个问题。

在子页面调出选择器的时候,年月日这些选项只能上划选择,不能下滑选择,原因也很简单,因为子页面有下拉刷新,下滑选择时间的时候,整个子页面都会下拉,这个问题我搜索了一下,真有解决方法,并且很好用。就是禁止页面刷新,结束后再重新释放。代码如下:

mui('#vmMain').pullRefresh().setStopped(true);//暂时禁止滚动
mui('#vmMain').pullRefresh().setStopped(false);//开启禁止滚动

下面说重写mui的选择器的picker的hide方法。
这是mui.picker.js的源码

hide: function() {
    var i = this;
    if(!i.disposed) {
        var n = i.ui;
        n.picker.classList.remove(e.className("active")), n.mask.close(),t.body.classList.remove(e.className("dtpicker-active-for-page")), e.back = i.__back
    }
},

需要重写的就是这部分代码,重写后的代码如下:

var params = { "type": "date"};
var dtPicker = new mui.DtPicker(params); 
//定义一个Boolean,控制选择器的弹出
var boo = true;
//重写日期选择器的hide方法 
dtPicker.hide = function(){
    boo = true;
    //隐藏选择器的时候把禁止滚动去掉
    mui('#vmMain').pullRefresh().setStopped(false);//开启禁止滚动
    var i = this;
    if(!i.disposed){
        var n=i.ui;
         n.picker.classList.remove(mui.className("active")),
         n.mask.close(),
         document.body.classList.remove(mui.className("dtpicker-active-for-page")),
         mui.back=i.__back
    }
}
下面贴稍微完整一些的代码,我会在注释里写清楚我每一步的思路:

父页面

//触发input的方法
blur(type){
    //定义的n初始值为0,每次点击input都+1;
    this.n++;
    var list = plus.webview.getWebviewById("dealer.html");
    //触发子页面的自定义事件 showPicker,
    mui.fire(list,"showPicker",{
        n:this.n//将n作为参数传过去,判断是否是第一次点击input
    })
    list.show();
},
//在子页面触发此事件 backPicker
window.addEventListener("backPicker",function(event){
    //每次返回首先将n重新赋值为0
    vm.$data.n = 0;
    //将子页面返回的时间值赋值给input框
    vm.$data.StartTime = event.detail.value;
})

子页面

//我只需要年月日,并不需要时分秒,故在此定义
var params = { "type": "date"};
//初始化时间选择器
var dtPicker = new mui.DtPicker(params); 
//定义boolean,用于判断选择器可以弹出的时间
var boo = true;
//重写日期选择器的hide方法 
 dtPicker.hide = function(){
    //将boo赋值为true,此步不用写,因为boo为true并未在其他地方改变过
    boo = true;
    //在选择器开启的时候会禁止页面滚动,隐藏的时候解开
    mui('#vmMain').pullRefresh().setStopped(false);//开启禁止滚动
    //下面这部分就是mui.picker.js的hide方法的源码了,我并没有深入分析,在此不再详解
    var i = this;
    if(!i.disposed){
        var n=i.ui;
        n.picker.classList.remove(mui.className("active")),
        n.mask.close(),
        document.body.classList.remove(mui.className("dtpicker-active-for-page")),
        mui.back=i.__back
    }
}
//自定义事件showPicker
window.addEventListener("showPicker",function(event){
    //禁止重复打开选择器  
    if(event.detail.n >= 2 && !boo)return;
    //当显示选择器之前 先将子页面禁止滚动
    mui('#vmMain').pullRefresh().setStopped(true);//暂时禁止滚动
    //当显示选择器
    dtPicker.show(function (res) {
        //点击选择器的确定按钮,首先页面设置为可以滚动  然后出发父页面的自定义事件backPicker, 将日期传过去
        mui('#vmMain').pullRefresh().setStopped(false);//开启禁止滚动
        var list = plus.webview.getWebviewById("dealer-main.html");
        mui.fire(list,"backPicker",{
            value:res.text
        })
        list.show();
    })
})

到此就结束了,可能有更简单且高效的方法吧,但我目前没查到,毕竟是渣渣,API都不熟悉
暂时还没测出问题,有问题再更新啦。
其实我还有个小需求,就是将选择器的取消按钮换成清空按钮,还在研究中......

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容