前端mobileWindow.js框架0.0.1版正式發佈,不足之處望指出

mobileWindow.js

由於公司的新項目須要在手機端實現相似APP的操做,爲了快速的開發固然但願找一個現成的第三方類庫來實現相關的功能,可是找了幾天,依然沒有找個特別合適的,因而就本身動手開始寫一套簡單的框架來實現該項目衆多的需求。javascript

此函數庫的主要做用爲了讓用戶打開手機端頁面,也像是在使用APP同樣。源碼借鑑了mobileSelect.js這個第三方工具類,框架的思想借鑑了Vue。css

GitHub地址:連接html

功能

  • 滑動選擇框
  • 手動輸入框,支持內容驗證
  • 標籤切換不一樣選框

特性

  • 原生js移動端選擇控件,不依賴任何庫
  • 可傳入普通數組或者json數組
  • 可根據傳入的參數長度,自動渲染出對應的列數,支持單項到多項選擇
  • 自動識別是否級聯
  • 選擇成功後,提供自定義回調函數callback() 返回當前選擇索引位置、以及選擇的數據(數組/json)
  • 每次手勢滑動結束後,也提供一個回調函數transitionEnd() 返回當前選擇索引位置、以及選擇的數據(數組/json)
  • 可以在已經實例化控件後,提供update函數再次渲染,可用於異步獲取數據或點擊交互後須要改變所選數據的場景
  • 提供重定位函數
  • 能夠回顯(第二次進入頁面時,能夠顯示歷史選擇的位置)

演示

手機頁面預覽:

真實項目體驗,手機端請打開:連接vue

可能由於帳號問題,某些同窗沒法看全功能,能夠在本代碼庫的demo目錄中查看全部的功能java

引入

方式一 標籤引入:

<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:git

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 數據源,須要顯示的數據
callback function(indexArr, data){} function 選擇成功後觸發的回調函數,返回indexArr、data
transitionEnd function(indexArr, data){} function 每一次手勢滑動結束後觸發的回調函數,返回indexArr、data
cancel function(indexArr, data){} function 返回的是indexArr和data是上一次點擊確認按鈕時的值
onShow function(e){} function 顯示控件後觸發的回調函數, 返回參數爲對象自己
onHide function(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 輪子背景顏色
maskOpacity 0.7 Number 遮罩透明度
keyMap {id:'id', value:'value', childs:'childs'} Object 字段名映射,適用於字段名不匹配id,value,childs的數據格式
triggerDisplayData true Boolean 在點擊確認時,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個)

基礎實例 → 功能函數操做後github

②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,完成初始化定位便可。ajax

項目demo:

使用transitionEnd()、callback()、updateWheel()、locatePosition()函數實現以下功能:vue-cli

  • 選擇當天日期時,不得超過今天已過期辰。
  • 選擇取車時間後,還車時間不得超過取車時間(包括日期和時間)。

更新日誌

2020-07-03[更新]

  • 增長使用標籤切換不一樣滑動框功能
  • 去除點擊某選項後,自動改變div的內容,改成返回點選的結果

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

  • 修復標籤切換後,多級聯顯示錯誤的問題
  • 增長彈出輸入框功能

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

  • 增長輸入框內容驗證

2020-07-10[修正]

  • 調整項目結構

2020-07-11[修正]

  • 優化例子代碼
  • 編寫例子說明

許可證

Copyright (c) 2020-present, Abbott Liunpm

相關文章
相關標籤/搜索