精华内容
下载资源
问答
  • weui picker实现

    千次阅读 2019-07-23 00:11:44
    link rel="stylesheet" href="./style/weui.css"/> #注意修改为自己的路径 在底部引入js文件:<script src="https://res.wx.qq.com/open/libs/weuijs/1.2.1/weui.min.js"></script> 在html中写入 ...

    在head中引入css文件: <link rel="stylesheet" href="./style/weui.css"/>  #注意修改为自己的路径

    在底部引入js文件:<script src="https://res.wx.qq.com/open/libs/weuijs/1.2.1/weui.min.js"></script>

    在html中写入

    <div>
        <a class="weui-cell weui-cell_access js_item" data-id="picker" href="javascript:;">  
          <div class="weui-cell__bd">
             <p>Picker</p>
          </div>
          <div class="weui-cell__ft"></div>
        </a>
    </div>

    #与自己在html中定义的元素id对应  例如我的示例data-id 为picker

    $('#picker').on('click', function () {
        weui.picker([{
            label: '飞机票',
            value: 0
        }, {
            label: '火车票',
            value: 1
        }, {
            label: '的士票',
            value: 2
        },{
            label: '公交票 (disabled)',
            disabled: true,
            value: 3
        }, {
            label: '其他',
            value: 4
        }], {
            onChange: function (result) {
                console.log(result);
            },
            onConfirm: function (result) {
                console.log(result);
            },
            title: '单列选择器'
        });
    });
    展开全文
  • weui-picker

    2020-12-25 21:02:34
    <div><p>如果是多列数据(2列以上),[defaultSelect] 和 [(ngModel)]共存的话有点问题。 [defaultSelect] 以这样的格式([defaultSelect]=...cipchk/ngx-weui</p></div>
  • weui的展示界面,有一个挺不错的picker模拟select的演示,但是我读了一遍weui.js的文档,却发现没有将select转为picker的这一过程封装,所以只好造了一个轮子,同时也上传到了github:weui.js-select2Picker ...

    在weui的展示界面,有一个挺不错的picker模拟select的演示,但是我读了一遍weui.js的文档,却发现没有将select转为picker的这一过程封装,所以只好造了一个轮子,同时也上传到了github:weui.js-select2Picker

    (() => {
        if (!weui || !$)
            return;
        weui.select2Picker = {
            init: () => {
                weui.select2Picker.initSelectChange();
                weui.select2Picker.initPcikerClick();
            },
            // 给select控件注册事件,改变时修改显示的值
            initSelectChange: () => {
                const pickerDoms = $('[pickerfrom]');
                $.each(pickerDoms, (i, dom) => {
                    const target = $(dom).attr('pickerfrom');
                    $('body').on('change', target, (e) => {
                        const $this = $(e.target);
                        if ($this.val()) {
                            weui.select2Picker.setValue($(`[pickerfrom="${target}"]`), $this.find(':checked').text());
                        }
                    });
                });
            },
            // 给显示控件注册点击事件,点击时生成picker的options,如果控件存在pickerdisabled类,则停止工作
            initPcikerClick: () => {
                $('[pickerfrom]').on('click', (e) => {
                    if ($(e.target).hasClass('pickerdisabled')) {
                        return;
                    }
                    const dom = $(e.target).attr('pickerfrom');
                    let values = weui.select2Picker.initPickerOptions(dom);
                    values = weui.select2Picker.uniqueOptions(values);
                    weui.select2Picker.showPicker(dom, values);
                });
            },
            // 显示picker
            showPicker: (dom, items, options) => {
                weui.picker(items, $.extend({
                    id: new Date().valueOf(),
                    defaultValue: weui.select2Picker.getSelectValue(dom),
                    onConfirm: function (result) {
                        const val = result[result.length - 1].value;
                        weui.select2Picker.setValue(dom, val);
                    }
                }, options));
            },
            // picker的items去重
            uniqueOptions: values => {
                const newArr = [];
                values.forEach(x => {
                    const exists = newArr.find(y => { return y.value == x.value });
                    if (exists) {
                        if (x.children && x.children.length > 0) {
                            if (!exists.children) {
                                exists.children = [];
                            }
                            x.children.forEach(child => {
                                exists.children.push(child);
                            });
                        }
                    } else {
                        newArr.push(x);
                    }
                });
                return newArr;
            },
            // 创建pickeritems,如果存在optgroup则生成两级item
            initPickerOptions: dom => {
                const $select = $(dom);
                let pickerOptions = [];
                if ($select.find('optgroup').length > 0) {
                    const $optgroup = $select.find('optgroup');
                    $.each($optgroup, (i, $group) => {
                        const $option = $($group).find('option:first');
                        if ($option.attr('label')) {
                            pickerOptions.push({
                                value: $($group).attr('label'),
                                label: $($group).attr('label'),
                                disabled: $($group).prop('disabled'),
                                children: weui.select2Picker.option2Picker($group)
                            });
                        }
                    });
                } else {
                    pickerOptions = weui.select2Picker.option2Picker($select);
                }
                return pickerOptions;
            },
            // 将option生成为item,如果有disabled则设置对应属性
            option2Picker: parent => {
                const $option = $(parent).find('option');
                const hadArr = [];
                $.each($option, (i, $opt) => {
                    if ($($opt).val()) {
                        hadArr.push({
                            value: $($opt).val(),
                            label: $($opt).text(),
                            disabled: $($opt).prop('disabled')
                        });
                    }
                });
                return hadArr;
            },
            // 获取select当前的值,用作picker的默认值
            getSelectValue: dom => {
                const $this = $(dom);
                const val = $this.val();
                const choose = [];
                if (!val) {
                    return choose;
                }
                if ($this.find(':checked').parent().attr('label')) {
                    choose.push($this.find(':checked').parent().attr('label'));
                }
                choose.push(val);
                return choose;
            },
            // 给select赋值并且触发change事件
            setValue: (target, val) => {
                const $dom = $(target);
                if ($dom.is('select') || $dom.is('input')) {
                    $dom.val(val);
                } else {
                    $dom.text(val);
                }
                $dom.trigger("change");
            }
        }
    })();
    

    在需要显示文字的控件部分配置pcikerfrom指定select,然后直接调用weui.select2pciker.init()方法即可。

    展开全文
  • 由于最近做的一个移动端项目需要使用到类似WeUI Picker组件的选择效果, 所以在这里来分析下 WeUI Picker的实现逻辑。(weui.js项目地址) 之前也做过类似的组件, 是基于iscroll实现的。单列滑动的效果还可以。至于多...

     

    前言

    由于最近做的一个移动端项目需要使用到类似 WeUI Picker组件 的选择效果,  所以在这里来分析下 WeUI Picker 的实现逻辑。(weui.js项目地址)

    之前也做过类似的组件, 是基于iscroll实现的。单列滑动的效果还可以。至于多列联动,数据结构整的太乱了, 不太好扩展。

     

    1.项目结构

    大家通过上面 weui.js 的项目地址去下载到本地, 打开之后找到 src 下面的 picker 就是我们今天要学习的 picker 组件的代码了。

    其中picker.js 和 scroll.js 就是我们主要研究的对象。

    1.1 picker.js

    在 picker.js 中有两个方法,picker 和 datePicker。其中 picker 是核心, datePicker 就是将日期数据整理好之后再去调用 picker

    以下是不包含 datePicker 的 picker 注释代码

      1 import $ from '../util/util';//dom选择器, 在balajs上面又添加了处理dom的方法
      2 import cron from './cron';//应用对应的日期规则,生成picker需要的数据格式
      3 import './scroll';//滑动核心
      4 import * as util from './util';//提供了一个获取数据嵌套深度的方法depthOf
      5 import pickerTpl from './picker.html';//picker组件的html模版
      6 import groupTpl from './group.html';//具体的每个滑动列表的html模版
      7 
      8 /**
      9  * 处理输入数据的每一项的结构成为 { label: item, value: item } 结构
     10  */
     11 function Result(item) {
     12     if(typeof item != 'object'){
     13         item = {
     14             label: item,
     15             value: item
     16         };
     17     }
     18     $.extend(this, item);
     19 }
     20 Result.prototype.toString = function () {
     21     return this.value;
     22 };
     23 Result.prototype.valueOf = function () {
     24     return this.value;
     25 };
     26 
     27 let _sington; // 单例模式, 创建完成后为当前实例, 关闭的时候设置为false
     28 let temp = {}; // temp 储存上一次滑动的位置
     29 
     30 function picker() {
     31     if (_sington) return _sington;//保证同时只能存在一个picker对象
     32 
     33     // 动态获取最后一个参数作为配置项
     34     const options = arguments[arguments.length - 1];
     35     // 扩展传入的配置项到默认值
     36     const defaults = $.extend({
     37         id: 'default',
     38         className: '',
     39         container: 'body',
     40         onChange: $.noop,
     41         onConfirm: $.noop,
     42         onClose: $.noop
     43     }, options);
     44 
     45     // 数据处理
     46     let items;
     47     let isMulti = false; // 是否多列的类型
     48     // 当参数大于2的时候说明是多列
     49     if (arguments.length > 2) {
     50         let i = 0;
     51         items = [];
     52         while (i < arguments.length - 1) {
     53             items.push(arguments[i++]);
     54         }
     55         isMulti = true;
     56     } else {
     57         items = arguments[0];
     58     }
     59 
     60     // 获取缓存
     61     temp[defaults.id] = temp[defaults.id] || [];
     62     // 选择结果, 会当作回调方法onChange的参数
     63     const result = [];
     64     // 根据id获取当前picker实例 选中的值的缓存, 所以声明实例的时候id要唯一
     65     const lineTemp = temp[defaults.id];
     66     // 根据模版和defaults渲染出dom,这里只渲染了一个className
     67     const $picker = $($.render(pickerTpl, defaults));
     68     // depth:数据结构的深度, 多列的时候就是列数, 单列的时候是嵌套的数据的深度。
     69     // groups:具体的滑动的列的html
     70     let depth = options.depth || (isMulti ? items.length : util.depthOf(items[0])), groups = '';
     71 
     72     // 显示与隐藏的方法
     73     function show(){
     74         //将渲染好的pciker插入到 设置的container中, 此时每一列的内容都还没有添加进去
     75         $(defaults.container).append($picker);
     76 
     77         // 这里获取一下计算后的样式,强制触发渲染. fix IOS10下闪现的问题
     78         $.getStyle($picker[0], 'transform');
     79 
     80         // 展示组件
     81         $picker.find('.weui-mask').addClass('weui-animate-fade-in');
     82         $picker.find('.weui-picker').addClass('weui-animate-slide-up');
     83     }
     84     function _hide(callback){
     85         _hide = $.noop; // 防止二次调用导致报错
     86 
     87         // 隐藏组件
     88         $picker.find('.weui-mask').addClass('weui-animate-fade-out');
     89         $picker.find('.weui-picker')
     90             .addClass('weui-animate-slide-down')
     91             .on('animationend webkitAnimationEnd', function () {
     92                 //动画结束后将picker移除, _sington设置为false, 执行onClose回掉, 执行hide函数传入的回掉。
     93                 $picker.remove();
     94                 _sington = false;
     95                 defaults.onClose();
     96                 callback && callback();
     97             });
     98     }
     99     function hide(callback){ _hide(callback); }
    100 
    101     /**
    102      * 初始化滚动的方法
    103      * level: 第几列或者嵌套的时候第几层
    104      * items: level对应的列的全部数据
    105      */
    106     function scroll(items, level) {
    107         if (lineTemp[level] === undefined && defaults.defaultValue && defaults.defaultValue[level] !== undefined) {
    108             // 没有缓存选项,而且存在defaultValue
    109             const defaultVal = defaults.defaultValue[level];
    110             let index = 0, len = items.length;
    111 
    112             // 取得默认值在items这一列中的index位置
    113             if(typeof items[index] == 'object'){
    114                 for (; index < len; ++index) {
    115                     if (defaultVal == items[index].value) break;
    116                 }
    117             }else{
    118                 for (; index < len; ++index) {
    119                     if (defaultVal == items[index]) break;
    120                 }
    121             }
    122 
    123             // 缓存当前实例的第level层的选中项的index
    124             if (index < len) {
    125                 lineTemp[level] = index;
    126             } else {
    127                 console.warn('Picker has not match defaultValue: ' + defaultVal);
    128             }
    129         }
    130         // 寻找到第level层对应的weui-picker__group容器进行 scroll 对应的事件的绑定
    131         // scroll的具体实现放在scroll.js之中
    132         /**
    133          * items: level对应的列的全部数据
    134          * temp: level选中项的索引
    135          */
    136         $picker.find('.weui-picker__group').eq(level).scroll({
    137             items: items,
    138             temp: lineTemp[level],
    139             onChange: function (item, index) {
    140                 //为当前的result赋值。把对应的第level层选中的值放到result中
    141                 if (item) {
    142                     result[level] = new Result(item);
    143                 } else {
    144                     result[level] = null;
    145                 }
    146                 //更新当前实例的第level层的选中项的索引
    147                 lineTemp[level] = index;
    148 
    149                 if (isMulti) {
    150                     // 多列的情况, 每一列都有选中的值的时候才会触发onChange回掉事件
    151                     if(result.length == depth){
    152                         defaults.onChange(result);
    153                     }
    154                 } else {
    155                     /**
    156                      * @子列表处理
    157                      * 1. 在没有子列表,或者值列表的数组长度为0时,隐藏掉子列表。
    158                      * 2. 滑动之后发现重新有子列表时,再次显示子列表。
    159                      *
    160                      * @回调处理
    161                      * 1. 因为滑动实际上是一层一层传递的:父列表滚动完成之后,会call子列表的onChange,从而带动子列表的滑动。
    162                      * 2. 所以,使用者的传进来onChange回调应该在最后一个子列表滑动时再call
    163                      */
    164                     if (item.children && item.children.length > 0) {
    165                         $picker.find('.weui-picker__group').eq(level + 1).show();
    166                         !isMulti && scroll(item.children, level + 1); // 不是多列的情况下才继续处理children
    167                     } else {
    168                         //如果子列表test不通过,子孙列表都隐藏。
    169                         const $items = $picker.find('.weui-picker__group');
    170                         $items.forEach((ele, index) => {
    171                             if (index > level) {
    172                                 $(ele).hide();
    173                             }
    174                         });
    175 
    176                         result.splice(level + 1);
    177 
    178                         defaults.onChange(result);
    179                     }
    180                 }
    181             },
    182             onConfirm: defaults.onConfirm
    183         });
    184     }
    185 
    186     // 根据depth添加对应的的滑动容器个数
    187     let _depth = depth;
    188     while (_depth--) {
    189         groups += groupTpl;
    190     }
    191     // 滑动容器添加到picker组件后展示出来
    192     $picker.find('.weui-picker__bd').html(groups);
    193     show();
    194 
    195     // 展示出picker组件后根据是否是多列采用, 采用不同的机制处理
    196     // 具体都是调用 scroll 处理每一列的元素的渲染和滚动绑定
    197     if (isMulti) {
    198         items.forEach((item, index) => {
    199             scroll(item, index);
    200         });
    201     } else {
    202         scroll(items, 0);
    203     }
    204 
    205     // 给picker 绑定对应的取消和确认事件
    206     $picker
    207         .on('click', '.weui-mask', function () { hide(); })
    208         .on('click', '.weui-picker__action', function () { hide(); })
    209         .on('click', '#weui-picker-confirm', function () {
    210             defaults.onConfirm(result);
    211         });
    212 
    213     // picker的dom元素赋值给到_sington并且绑定hide函数后返回
    214     _sington = $picker[0];
    215     _sington.hide = hide;
    216     return _sington;
    217 }
    View Code

     

    1.2 scroll.js

    本来想给scroll.js写点注释的, 后来发现人家注释已经写的很好了,  OTZ。

      1 import $ from '../util/util';
      2 
      3 /**
      4  * set transition
      5  * @param $target
      6  * @param time
      7  */
      8 const setTransition = ($target, time) => {
      9     return $target.css({
     10         '-webkit-transition': `all ${time}s`,
     11         'transition': `all ${time}s`
     12     });
     13 };
     14 
     15 
     16 /**
     17  * set translate
     18  */
     19 const setTranslate = ($target, diff) => {
     20     return $target.css({
     21         '-webkit-transform': `translate3d(0, ${diff}px, 0)`,
     22         'transform': `translate3d(0, ${diff}px, 0)`
     23     });
     24 };
     25 
     26 /**
     27  * @desc get index of middle item
     28  * @param items
     29  * @returns {number}
     30  */
     31 const getDefaultIndex = (items) => {
     32     let current = Math.floor(items.length / 2);
     33     let count = 0;
     34     while (!!items[current] && items[current].disabled) {
     35         current = ++current % items.length;
     36         count++;
     37 
     38         if (count > items.length) {
     39             throw new Error('No selectable item.');
     40         }
     41     }
     42 
     43     return current;
     44 };
     45 
     46 const getDefaultTranslate = (offset, rowHeight, items) => {
     47     const currentIndex = getDefaultIndex(items);
     48 
     49     return (offset - currentIndex) * rowHeight;
     50 };
     51 
     52 /**
     53  * get max translate
     54  * @param offset
     55  * @param rowHeight
     56  * @returns {number}
     57  */
     58 const getMax = (offset, rowHeight) => {
     59     return offset * rowHeight;
     60 };
     61 
     62 /**
     63  * get min translate
     64  * @param offset
     65  * @param rowHeight
     66  * @param length
     67  * @returns {number}
     68  */
     69 const getMin = (offset, rowHeight, length) => {
     70     return -(rowHeight * (length - offset - 1));
     71 };
     72 
     73 $.fn.scroll = function (options) {
     74     const defaults = $.extend({
     75         items: [],                                  // 数据
     76         scrollable: '.weui-picker__content',        // 滚动的元素
     77         offset: 3,                                  // 列表初始化时的偏移量(列表初始化时,选项是聚焦在中间的,通过offset强制往上挪3项,以达到初始选项是为顶部的那项)
     78         rowHeight: 34,                              // 列表每一行的高度
     79         onChange: $.noop,                           // onChange回调
     80         temp: null,                                 // translate的缓存
     81         bodyHeight: 7 * 34                          // picker的高度,用于辅助点击滚动的计算
     82     }, options);
     83     const items = defaults.items.map((item) => {
     84         return `<div class="weui-picker__item${item.disabled ? ' weui-picker__item_disabled' : ''}">${typeof item == 'object' ? item.label : item}</div>`;
     85     }).join('');
     86     const $this = $(this);
     87 
     88     $this.find('.weui-picker__content').html(items);
     89 
     90     let $scrollable = $this.find(defaults.scrollable);        // 可滚动的元素
     91     let start;                                                  // 保存开始按下的位置
     92     let end;                                                    // 保存结束时的位置
     93     let startTime;                                              // 开始触摸的时间
     94     let translate;                                              // 缓存 translate
     95     const points = [];                                          // 记录移动点
     96     const windowHeight = window.innerHeight;                    // 屏幕的高度
     97 
     98     // 首次触发选中事件
     99     // 如果有缓存的选项,则用缓存的选项,否则使用中间值。
    100     if(defaults.temp !== null && defaults.temp < defaults.items.length) {
    101         const index = defaults.temp;
    102         defaults.onChange.call(this, defaults.items[index], index);
    103         translate = (defaults.offset - index) * defaults.rowHeight;
    104     }else{
    105         const index = getDefaultIndex(defaults.items);
    106         defaults.onChange.call(this, defaults.items[index], index);
    107         translate = getDefaultTranslate(defaults.offset, defaults.rowHeight, defaults.items);
    108     }
    109 
    110     //初始化的时候先根据上面代码 计算出来的 初始化 translate 运动一次
    111     setTranslate($scrollable, translate);
    112 
    113     const stop = (diff) => {
    114         //根据 计算出来的位移量diff 与 当前的偏移量translate 相加
    115         translate += diff;
    116 
    117         // 移动到最接近的那一行
    118         translate = Math.round(translate / defaults.rowHeight) * defaults.rowHeight;
    119         const max = getMax(defaults.offset, defaults.rowHeight);
    120         const min = getMin(defaults.offset, defaults.rowHeight, defaults.items.length);
    121         // 不要超过最大值或者最小值
    122         if (translate > max) {
    123             translate = max;
    124         }
    125         if (translate < min) {
    126             translate = min;
    127         }
    128 
    129         // 如果是 disabled 的就跳过
    130         let index = defaults.offset - translate / defaults.rowHeight;
    131         while (!!defaults.items[index] && defaults.items[index].disabled) {
    132             diff > 0 ? ++index : --index;
    133         }
    134         translate = (defaults.offset - index) * defaults.rowHeight;
    135         setTransition($scrollable, .3);
    136         setTranslate($scrollable, translate);
    137 
    138         // 触发选择事件
    139         defaults.onChange.call(this, defaults.items[index], index);
    140     };
    141 
    142     function _start(pageY){
    143         start = pageY;
    144         startTime = +new Date();
    145     }
    146     function _move(pageY){
    147         end = pageY;
    148         const diff = end - start;
    149 
    150         setTransition($scrollable, 0);
    151         setTranslate($scrollable, (translate + diff));
    152         startTime = +new Date();
    153         points.push({time: startTime, y: end});
    154         if (points.length > 40) {
    155             points.shift();
    156         }
    157     }
    158     function _end(pageY){
    159         if(!start) return;
    160 
    161         /**
    162          * 思路:
    163          * 0. touchstart 记录按下的点和时间
    164          * 1. touchmove 移动时记录前 40个经过的点和时间
    165          * 2. touchend 松开手时, 记录该点和时间. 如果松开手时的时间, 距离上一次 move时的时间超过 100ms, 那么认为停止了, 不执行惯性滑动
    166          *    如果间隔时间在 100ms 内, 查找 100ms 内最近的那个点, 和松开手时的那个点, 计算距离和时间差, 算出速度
    167          *    速度乘以惯性滑动的时间, 例如 300ms, 计算出应该滑动的距离
    168          */
    169         const endTime = new Date().getTime();
    170         const relativeY = windowHeight - (defaults.bodyHeight / 2);
    171         end = pageY;
    172 
    173         // 如果上次时间距离松开手的时间超过 100ms, 则停止了, 没有惯性滑动
    174         if (endTime - startTime > 100) {
    175             //如果end和start相差小于10,则视为
    176             if (Math.abs(end - start) > 10) {
    177                 stop(end - start);
    178             } else {
    179                 stop(relativeY - end);
    180             }
    181         } else {
    182             if (Math.abs(end - start) > 10) {
    183                 const endPos = points.length - 1;
    184                 let startPos = endPos;
    185                 for (let i = endPos; i > 0 && startTime - points[i].time < 100; i--) {
    186                     startPos = i;
    187                 }
    188 
    189                 if (startPos !== endPos) {
    190                     const ep = points[endPos];
    191                     const sp = points[startPos];
    192                     const t = ep.time - sp.time;
    193                     const s = ep.y - sp.y;
    194                     const v = s / t; // 出手时的速度
    195                     const diff = v * 150 + (end - start); // 滑行 150ms,这里直接影响“灵敏度”
    196                     stop(diff);
    197                 }
    198                 else {
    199                     stop(0);
    200                 }
    201             } else {
    202                 stop(relativeY - end);
    203             }
    204         }
    205 
    206         start = null;
    207     }
    208 
    209     /**
    210      * 因为现在没有移除匿名函数的方法,所以先暴力移除(offAll),并且改变$scrollable。
    211      */
    212     $scrollable = $this
    213         .offAll()
    214         .on('touchstart', function (evt) {
    215             _start(evt.changedTouches[0].pageY);
    216         })
    217         .on('touchmove', function (evt) {
    218             _move(evt.changedTouches[0].pageY);
    219             evt.preventDefault();
    220         })
    221         .on('touchend', function (evt) {
    222             _end(evt.changedTouches[0].pageY);
    223         })
    224         .find(defaults.scrollable);
    225 
    226     // 判断是否支持touch事件 https://github.com/Modernizr/Modernizr/blob/master/feature-detects/touchevents.js
    227     const isSupportTouch = ('ontouchstart' in window) || window.DocumentTouch && document instanceof window.DocumentTouch;
    228     if(!isSupportTouch){
    229         $this
    230             .on('mousedown', function(evt){
    231                 _start(evt.pageY);
    232                 evt.stopPropagation();
    233                 evt.preventDefault();
    234             })
    235             .on('mousemove', function(evt){
    236                 if(!start) return;
    237 
    238                 _move(evt.pageY);
    239                 evt.stopPropagation();
    240                 evt.preventDefault();
    241             })
    242             .on('mouseup mouseleave', function(evt){
    243                 _end(evt.pageY);
    244                 evt.stopPropagation();
    245                 evt.preventDefault();
    246             });
    247 
    248     }
    249 };
    View Code

     

    1.3 抽取picker

    研究完了, 肯定要想着怎么使用起来。

    但是我们可能只想使用 picker 组件, 所以我这里把 picker 单独打包压缩了一份放到github上,  抽取之后的picker.min.js比原来的weui.min.js少了一大半的体积。(weuiPicker项目地址)

    有需要的童鞋可以自取, 也可以根据weui的项目自行打包。

     

    ps: 第一次写, 有不合理的地方请大家多多指正 : )

    转载于:https://www.cnblogs.com/haha1212/p/8393243.html

    展开全文
  • 于是选择了weui库中的Picker组件 原始需求与默认Picker组件UI不一致 UI图中的选择框每行高度与weui picker默认的每行高度不一致。于是想要改变picker组件的rowHeight高度。在picker api中并没有提供设置rowHeight...

    需求背景

    移动端H5项目,需要做省市区三级联动选择框,如下图:
    省市区三级联动图
    于是选择了weui库中的Picker组件

    原始需求与默认Picker组件UI不一致

    UI图中的选择框每行高度与weui picker默认的每行高度不一致。于是想要改变picker组件的rowHeight高度。在picker api中并没有提供设置rowHeight参数的接口。于是只能把源库下载到本地进行修改。
    在这里插入图片描述

    修改picker 默认的每行高度rowHeight

    想要修改选择框每行高度,要从两方面考虑:
    1、CSS修改

    // 修改选框的高度,为了适配,rem作为单位
    .weui-picker__indicator {
    	height:.9rem;
    }
    

    2、JS修改(picker有滑动选择效果,涉及到一些滑动计算)

    // 修改scroll方法,设置rowHeight为0.9rem,为了适配,这里设置为0.9*window.realFontSize
    o.default.fn.scroll = function (e) {
       var t = this, n = o.default.extend({
           items: [],
           scrollable: ".weui-picker__content",
           offset: 2,
           // rowHeight: 32, // 原始每行高度,px为单位
           rowHeight: 0.9 * window.realFontSize,
           onChange: o.default.noop,
           temp: null,
           // bodyHeight: 476 // 可滑动content总高度
           bodyHeight: 0.9 * window.realFontSize * 5
       }, e), i = n.items.map(function (e) {....
    
    // 修改计算当前选中行的方法
    var g = function (e) {
       h += e, h = Math.round(h / n.rowHeight) * n.rowHeight;
       var i = f(n.offset, n.rowHeight), o = s(n.offset, n.rowHeight, n.items.length);
       h > i && (h = i), h < o && (h = o);
       // 原始计算当前选中行的方法,var l = n.offset - h / n.rowHeight
       // for (var l = n.offset - h / n.rowHeight; n.items[l] && n.items[l].disabled;)e > 0 ? ++l : --l;
       // 修改如下:,rem为单位,不同机型得到的实际px不一样,l = n.offset - h / n.rowHeight得到的结果为小数,例如58.99999999(IOS13),不是整数,导致有些机型无法正确选中每行数据,因此我们要对l取整Math.round()。
       for (var l = Math.round(n.offset - h / n.rowHeight); n.items[l] && n.items[l].disabled;)e > 0 ? ++l : --l;
       
       console.log('l', l, n.items[l])
        h = (n.offset - l) * n.rowHeight, r(a, .3), u(a, h), 
        // 触发onChange函数
        n.onChange.call(t, n.items[l], l)
     };
    

    3、附计算realFontSize方法

    (function () {
            var ua = navigator.userAgent;
            var isAndroid = /Android/i.test(ua);
            var DESIGN_WIDTH = 750;
            var DESIGN_dpr = 2;
            var DESIGN_ROOT_FONT_SIZE = 100;
            var dpr = window.devicePixelRatio;
            var dpiWidth = screen.width;
            if (isAndroid) {
                dpr = 1;
            }
            var realScale = 1 / dpr;
            document.write('<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=' +
                realScale + ', maximum-scale=' + realScale + ', minimum-scale=' + realScale + '" />');
            var docWidth = document.documentElement.getBoundingClientRect().width;
            if (isAndroid) {
                dpiWidth = docWidth;
            }
            var realFontSize = dpiWidth * dpr / DESIGN_WIDTH * DESIGN_ROOT_FONT_SIZE;
            window.realFontSize = realFontSize;
            document.getElementsByTagName("html")[0].style.fontSize = realFontSize + "px";
        })();
    
    展开全文
  • weui-picker蒙层问题

    2021-03-23 22:12:42
    weui-picker蒙层问题 问题描述:点击选择框以外的地方不关闭select,并且无阴影 解决方法: 在css加一行代码: .weui-animate-fade-in { visibility: unset !important; }
  • 最近用jquery weui. 在使用picker时需要一些问题. 就是让picker 显示label, 但是取值的时候取value用于存储. 官网例子如下 Jquery-weui 官网 :点这里写这篇文章时,用的版本是1.2.1版本 $("#picker-name")....
  • 前言:由于最近做的一个移动端项目需要用到类似WeUI Picker组件的选择效果,所以下面来分析下WeUI Picker的实现逻辑。(weui.js项目地址) 之前也做过类似的组件,是基于iscroll实现的。单列滑动的效果还可以。至于...
  • jqweuipicker动态加载数据 jqweui是jquery对weui的拓展开发,picker就是其中的一个拓展组件。 如果是动态加载数据的话,可以把加载方法写成一个方法,数据是加载后返回的再填充。但是有一个问题,前台要求的数据...
  • jqweuipicker动态加载数据

    千次阅读 2017-12-04 18:30:10
    weuipicker动态加载数据
  • vue.js里想用weuipicker,也引入了weui.js,为什么报错weui is not defined?import weuiJs from '../weui-js/weui.js'export default {methods: {checkPicker: function () {weui.picker([{label: '飞机票',value...
  • WEUI Picker不切换数据

    2018-12-26 22:16:00
    ).picker({ title: "请选择摄像头" , cols: [ { textAlign: 'center' , values: [ '前置摄像头' ] } ] }); } else { $( "#box").empty(); $("#box").html("前置摄像头'/>" ); $( "#camera" )....
  • WeUI picker 如何动态设置defaultValue

    千次阅读 2018-12-30 19:19:01
    WeUI picker 如何动态设置defaultValue 我这里做的是四色球的设计.每次点击随机生成一注,发行defaultValue不会自动变化,看到源码发行 他们使用了temp[option.id]缓存了上次的defaultValue,导致,动态设置default...
  • weui.picker 乱码处理

    2020-05-22 11:09:33
    注:https://www.cnblogs.com/iLoveMyD/p/11081625.html
  • WEUI picker组件无法js动态改变选项

    千次阅读 2018-06-12 12:28:09
    功能需求 ...一般情况下,这个需求很简单,当选择设备号的时候js动态改变摄像头选项里面的值就可以了,但是WEUI picker和Select组件都不支持动态改变选项,只支持初始赋值。 解决方案 因为picker和Sel...
  • 地址:http://jqweui.com/extends#picker加了Display Value后,会产生改变值后,Picker显示Value而不显示Text情况。需要在OnClose里做如下处理。 texts: ['赵', '钱', '孙', '李', '周', '吴', '郑', '王'] values...
  • 前言 ...弹出来 选择年月日的框之后,直接点击导航上的“返回” 按钮,picker 选框不消失,也就是弹出框不消失 weui.datePicker({ start: 1900, // 从今天开始 end: 2030, defaultVal...
  •  picker和Select组件是通过input标签绑定,可以先通过input的父级元素移除input标签,重新插入input标签,最后重新初始化picker或Select组件。 <div class=weui-cell> <div class=weui-cell__hd>...
  • weuiPicker的使用教程

    万次阅读 2016-12-10 16:14:22
    这个问题调试了很久,因为调用example.js时没问题,一移开就失效,一度觉得很诡异。 经过多次测试,才发现,是zepto.min.js的次序放错了... WeUI 单列选择器 $('#showPicker').on('click', function
  • $('#showPicker').on('click', function () { weui.picker(data, { onChange: function (result) { }, onConfirm: function (resu...
  • weui picker自定义城市选择-踩过的坑

    千次阅读 2019-12-13 17:49:30
    在做项目需要自定义城市选择,所以从数据库中读取。需要显示省市两级联动,取出的数据...因为weui picker关键字是固定的,不能使用city 需要使用约定好的 children 如图: 这样就可以了。 此坑记录下来,谨记! ...
  • JQuery-weui city-picker动态加载数据

    千次阅读 2019-11-21 01:00:25
    JQuery-weui city-picker动态加载数据 JQuery-weui city-picker 加载三级菜单 页面代码: <html> <head> <meta charset="utf-8"/> <script type="text/javascript" src="jquery....
  • var date = new Date(); var month = date.getMonth()+1; //获取当前月份 var year=date.getFullYear(); //获取年份 ... $('#selectTime').picker({ toolbarTemplate:'<div class="toolbar">...
  •  picker和Select组件是通过input标签绑定,可以先通过input的父级元素移除input标签,重新插入input标签,最后重新初始化picker或Select组件。性别js代码:$("#appl_sex").picker({title: "请选择",cols: [{...
  • var date = new Date() var month = date.getMonth()+1 //获取当前月份 ... $('#selectTime').picker({ toolbarTemplate:'<div class="toolbar"><div class="toolbar-inner">&...
  • 说明 主要利用jquery-weui插件,...css只用到了Picker部分的css 实现 引入jquery手册,引入jquery-weui.js,在我的源码中一定要引入base.css中必要的weui中的样式,之后上代码 实现过程 html文件 <body&...

空空如也

空空如也

1 2 3 4 5 ... 8
收藏数 155
精华内容 62
关键字:

pickerweui