mobileWindow.js

因为公司的新我的项目须要在手机端实现相似APP的操作,为了疾速的开发当然心愿找一个现成的第三方类库来实现相干的性能,然而找了几天,仍然没有找个特地适合的,于是就本人入手开始写一套简略的框架来实现该我的项目泛滥的需要。

此函数库的次要作用为了让用户关上手机端页面,也像是在应用APP一样。源码借鉴了mobileSelect.js这个第三方工具类,框架的思维借鉴了Vue。

GitHub地址:链接

性能

  • 滑动抉择框
  • 手动输入框,反对内容验证
  • 标签切换不同选框

个性

  • 原生js挪动端抉择控件,不依赖任何库
  • 可传入一般数组或者json数组
  • 可依据传入的参数长度,主动渲染出对应的列数,反对单项到多项抉择
  • 自动识别是否级联
  • 抉择胜利后,提供自定义回调函数callback() 返回以后抉择索引地位、以及抉择的数据(数组/json)
  • 每次手势滑动完结后,也提供一个回调函数transitionEnd() 返回以后抉择索引地位、以及抉择的数据(数组/json)
  • 可能在曾经实例化控件后,提供update函数再次渲染,可用于异步获取数据或点击交互后须要扭转所选数据的场景
  • 提供重定位函数
  • 能够回显(第二次进入页面时,能够显示历史抉择的地位)

演示

手机页面预览:

实在我的项目体验,手机端请关上:链接

可能因为账号问题,某些同学无奈看全功能,能够在本代码库的demo目录中查看所有的性能

引入

形式一 标签引入:

<link rel="stylesheet" type="text/css" href="assets/styles/mobileWindow.css"><script src="assets/scripts/mobileWindow.js" type="text/javascript"></script>

形式二 npm:

npm install mobile-window -D

在你的js文件中import:

import MobileWindow from 'mobile-window'

抉择框(无标签)- 疾速应用

①一般数组格局-非联动

<div id="trigger1"></div> <!--页面中别漏了这个trigger--><script type="text/javascript">var mobileSelect1 = new MobileSelect({    trigger: '#trigger1',    title: '单项抉择',    wheels: [                {data:['周日','周一','周二','周三','周四','周五','周六']}            ],    position:[2] //初始化定位});</script>

②json格局-非联动

<div id="trigger2"></div><script type="text/javascript">var mobileSelect2 = new MobileSelect({    trigger: '#trigger2',    title: '地区抉择',    wheels: [                {data:[                    {id:'1',value:'左近'},                    {id:'2',value:'上城区'},                    {id:'3',value:'下城区'},                    {id:'4',value:'江干区'},                    {id:'5',value:'拱墅区'},                    {id:'6',value:'西湖区'}                ]},                {data:[                    {id:'1',value:'1000米'},                    {id:'2',value:'2000米'},                    {id:'3',value:'3000米'},                    {id:'4',value:'5000米'},                    {id:'5',value:'10000米'}                ]}            ],    callback:function(indexArr, data){        console.log(data); //返回选中的json数据    }});</script>
效果图:

③json格局-联动

<div id="trigger3"></div><script type="text/javascript">  var mobileSelect3 = new MobileSelect({      trigger: '#trigger3',      title: '地区抉择-联动',      wheels: [                  {data:[                      {                          id:'1',                          value:'左近',                          childs:[                              {id:'1',value:'1000米'},                              {id:'2',value:'2000米'},                              {id:'3',value:'3000米'},                              {id:'4',value:'5000米'},                              {id:'5',value:'10000米'}                          ]                      },                      {id:'2',value:'上城区'},                      {id:'3',value:'下城区'},                      {id:'4',value:'江干区'},                      {id:'5',value:'拱墅区'},                      {id:'6',value:'西湖区'}                  ]}              ],      position:[0,1],      callback:function(indexArr, data){          console.log(data); //返回选中的json数据      }  });  </script>
效果图:

④在vue-cli中如何应用

npm install mobile-select -D
<template>    <div>        <div id="trigger4">单项抉择</div>    </div></template><script>    import MobileSelect from 'mobile-select'    export default {        mounted() {            var mobileSelect4 = new MobileSelect({                trigger: "#trigger4",                title: "单项抉择",                wheels: [                    {data: ["周日","周一","周二","周三","周四","周五","周六"]}                ],                callback:function(indexArr, data){                    console.log(data);                }            });        }    }</script>

⑤数据字段名映射

<div id="trigger5"></div><script type="text/javascript">    //如果你的数据的字段名为id,title,children    //与mobileSelect的id,value,childs字段名不匹配    //能够用keyMap属性进行字段名映射    var mobileSelect5 = new MobileSelect({        trigger: '#trigger5',        title: '数据字段名映射',        wheels: [                    {data:[                        {                            id:'1',                            title:'A',                            children:[                                {id:'A1',title:'A-a'},                                {id:'A2',title:'A-b'},                                {id:'A3',title:'A-c'}                            ]                        },                        {                            id:'1',                            title:'B',                            children:[                                {id:'B1',title:'B-a'},                                {id:'B2',title:'B-b'},                                {id:'B3',title:'B-c'}                            ]                        },                    ]}                ],        keyMap: {            id:'id',            value: 'title',            childs :'children'        },        callback:function(indexArr, data){            console.log(data);        }    });</script>

输入框(无标签)- 疾速应用

输出内容

<div id="trigger-input"></div>var mobileWindowInput = new MobileWindow({    // trigger: '#lease-type-trigger',    // title: '租房类型选项',    trigger: {        type: 'input',        element: '#trigger-input',    },    title: '请输出内容',    transitionEnd:function(indexArr, data){        //console.log(data);    },    callback:function(data){        console.log(data);        // mobileWindowRental.validateRegex(123);        // if(regInt.test(data.valueInput)) {        document.getElementById('trigger-input').innerHTML = data['valueInput']    }});

输出内容 - 验证内容格局

<div id="month-amount-wrapper"></div>var mobileWindowRental = new MobileWindow({    // trigger: '#lease-type-trigger',    // title: '租房类型选项',    trigger: {        type: 'input',        element: '#month-amount-wrapper',    },    title: '请输出金额',    inputTrim: true,    inputCheckType: ['number'],    transitionEnd:function(indexArr, data){        //console.log(data);    },    callback:function(data){        console.log(data);        // mobileWindowRental.validateRegex(123);        // if(regInt.test(data.valueInput)) {        if(data['checkType'][0]) {            document.getElementById('month-amount-wrapper').style.color = '#000000';            document.getElementById('month-amount-wrapper').innerHTML = data.valueInput;        } else {            var strPrompt = '请填写整数';            document.getElementById('month-amount-wrapper').style.color = '#000000';            document.getElementById('month-amount-wrapper').innerHTML = strPrompt;        }    }});

抉择框(有标签)- 疾速应用

<div id="trigger6" class="trigger-tag-selector">    <div id="house-floor-container">楼层</div>    <div id="house-elevator-container">电梯</div></div>
var floorArr = [];var floorTotalArr = [];var floorNeed = 53; // 共50层for(var iFloor = 0; iFloor<floorNeed; iFloor++) {    floorArr[iFloor] = iFloor-2 + '层';}for(var iFloor = 0; iFloor<floorNeed-3; iFloor++) {    floorTotalArr[iFloor] = '共' + (iFloor+1) +'层';}var arrHouseFloor = [    floorArr,    floorTotalArr,];var arrHouseElevator = ['有电梯', '无电梯'];var arrTypes = [arrHouseFloor, arrHouseElevator];var mobileSelectFloorElevator = new MobileWindow({    // trigger: '#lease-type-trigger',    // title: '租房类型选项',    trigger: {        type: ['select', 'select'],        element: ['#house-floor-container', '#house-elevator-container'],        tags:['楼层', '电梯'],    },    title: ['请抉择楼层', '请抉择电梯'],    wheels: [        {            data: arrTypes,        },    ],    position:[0, 0], //初始化定位 关上时默认选中的哪个 如果不填默认为0    transitionEnd:function(indexArr, data){        //console.log(data);    },    beforeCreate: function() {    },    created: function () {        // `this` 指向 vm 实例        console.log('a is: ' + this.a)    },    beforeMount: function() {    },    callback: function(tagIndex, indexArr, data){        console.log(tagIndex, '/', indexArr, '/', data);    }});

参数

选项默认值类型形容
trigger必填参数 无默认值String触发对象的id/class/tag
wheels必填参数 无默认值Array数据源,须要显示的数据
callbackfunction(indexArr, data){}function抉择胜利后触发的回调函数,返回indexArr、data
transitionEndfunction(indexArr, data){}function每一次手势滑动完结后触发的回调函数,返回indexArr、data
cancelfunction(indexArr, data){}function返回的是indexArr和data是上一次点击确认按钮时的值
onShowfunction(e){}function显示控件后触发的回调函数, 返回参数为对象自身
onHidefunction(e){}function暗藏控件后触发的回调函数, 返回参数为对象自身
title''String控件题目
position[0,0,0,…]Array初始化定位
connector' 'String多个轮子时,多个值两头的连接符,默认是空格
ensureBtnText'确认'String确认按钮的文本内容
cancelBtnText'勾销'String勾销按钮的文本内容
ensureBtnColor'#1e83d3'String确认按钮的文本色彩
cancelBtnColor'#666666'String勾销按钮的文本色彩
titleColor'#000000'String控件题目的文本色彩
titleBgColor'#ffffff'String控件题目的背景色彩
textColor'#000000'String轮子内文本的色彩
bgColor'#ffffff'String轮子背景色彩
maskOpacity0.7Number遮罩透明度
keyMap{id:'id', value:'value', childs:'childs'}Object字段名映射,实用于字段名不匹配id,value,childs的数据格式
triggerDisplayDatatrueBoolean在点击确认时,trigger的innerHtml是否变为抉择的数据。
(如果trigger外面还有其余元素,则能够设置为false;如果须要在别的中央显示数据,则可用callback返回的数据自行拼接)

注:回调函数中返回的参数含意如下

  • indexArr是以后选中的索引数组 如[0,0,1] 代表有三个轮子 选中的数据是第一个轮子的第0个数据、第二个轮子的第0个数据、第三个轮子的第1个数据
  • data是以后选中的json数据 如[{id:'1',value:'hello'},{id:'2',value:'world'}]

性能函数:

函数名参数形容
show()无参手动显示弹窗组件
hide()无参手动暗藏弹窗组件
setTitle()string设置控件的题目
locatePosition()sliderIndex, posIndex传入地位数组,从新定位轮子选中的地位
updateWheel()sliderIndex, data从新渲染指定的轮子
updateWheels()data从新渲染所有轮子(仅限级联数据格式应用)
getValue()无参获取组件抉择的值

注:性能函数中须要传递的参数含意如下

  • sliderIndex 代表的是要批改的轮子的索引
  • posIndex 代表地位索引

①性能函数demo:

<div id="day"></div>var mySelect = new MobileSelect({    trigger: '#day',    wheels: [                {data:['周日','周一','周二','周三','周四','周五','周六']},                {data:['08:00','09:00','10:00','11:00','12:00','13:00','14:00']}            ],    position:[1,1] //初始化定位 两个轮子都选中在索引1的选项});//----------------------------------------------//进行根底的实例化之后,对实例用性能函数操作// mySelect.setTitle('啦啦啦(•ㅁ•)');// 设置控件的题目// mySelect.updateWheel(0,['sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday']);// 更新第0个轮子的数据,数据变为英文的星期几// mySelect.locatePosition(1,0);// 从新定位第1个轮子的地位,将第1个轮子的第0个数据改为以后选中。// (第1个轮子是指左边的轮子,右边的轮子是第0个)

根底实例 → 性能函数操作后

②ajax异步填充数据demo

<!-- ************ 非级联格局 ************ --><div id="trigger6"></div><script type="text/javascript">    var mobileSelect6 = new MobileSelect({        trigger: '#trigger6',        title: 'ajax填充数据-非级联',        wheels: [                    {data:[                        {id:'1',value:'请抉择地区'},                    ]},                    {data:[                        {id:'1',value:'请抉择间隔'},                    ]}                ],        callback:function(indexArr, data){            console.log(data);        }    });    $.ajax({        type: "POST",        url: "xxxx",        data: {},        dataType: "json",        success: function(res){            //这里假如获取到的res.data.area为:            // [            //     {id:'1',value:'左近'},            //     {id:'2',value:'福田区'},            //     {id:'3',value:'罗湖区'},            //     {id:'4',value:'南山区'}            // ]            //这里假如获取到的res.data.distance为:            // [            //     {id:'1',value:'200米'},            //     {id:'2',value:'300米'},            //     {id:'3',value:'400米'}            // ]            mobileSelect6.updateWheel(0, res.data.area); //更改第0个轮子            mobileSelect6.updateWheel(1, res.data.distance); //更改第1个轮子        }    });</script></script><!-- ************ 级联格局 ************ --><div id="trigger7"></div><script type="text/javascript">    var mobileSelect7 = new MobileSelect({        trigger: '#trigger7',        title: 'ajax填充数据-级联',        wheels: [                    {data:[                        {                            id:'1',                            value:'',                            childs:[                                {id:'A1',value:''},                            ]                        }                    ]}                ],        callback:function(indexArr, data){            console.log(data);        }    });    $.ajax({        type: "POST",        url: "xxxx",        data: {},        dataType: "json",        success: function(res){            //这里假如获取到的res.data为:            // [{            //     id:'1',            //     value:'更新后数据',            //     childs:[            //         {id:'A1',value:'apple'},            //         {id:'A2',value:'banana'},            //         {id:'A3',value:'orange'}            //     ]            // }]            mobileSelect7.updateWheels(res.data);        }    });</script>

如何回显抉择的地位

callback回调函数里有一个indexArr参数,它是一个数组,记录着以后选中的地位:
把这个数组转化为字符串之后,能够用<input type="hidden" value="">暗藏域或者别的其余形式保留下来,传给后盾。
下次关上页面时,
MobileWindow实例化的时候,读取这个字符串,再转成数组,传给position,实现初始化定位即可。

我的项目demo:

应用transitionEnd()、callback()、updateWheel()、locatePosition()函数实现如下性能:

  • 抉择当天日期时,不得超过明天已过时刻。
  • 抉择取车工夫后,还车工夫不得超过取车工夫(包含日期和工夫)。

更新日志

2020-07-03[更新]

  • 减少应用标签切换不同滑动框性能
  • 去除点击某选项后,主动扭转div的内容,改为返回点选的后果

2020-07-05[更新+修改]

  • 修复标签切换后,多级联显示谬误的问题
  • 减少弹出输入框性能

2020-07-08[更新+修改]

  • 减少输入框内容验证

2020-07-10[修改]

  • 调整我的项目构造

2020-07-11[修改]

  • 优化例子代码
  • 编写例子阐明

许可证

Copyright (c) 2020-present, Abbott Liu