weui picker组件 单位使用rem,滑动的时候,解决位置不对称问题

在weui.js源码中找到以下方法:

_util2.default.fn.scroll = function (options) {
                var _this = this;

                var defaults = _util2.default.extend({
                    items: [], // 数据
                    scrollable: '.weui-picker__content', // 滚动的元素
                    offset: 2, // 列表初始化时的偏移量(列表初始化时,选项是聚焦在中间的,通过offset强制往上挪3项,以达到初始选项是为顶部的那项)
                    rowHeight: 48, // 列表每一行的高度
                    onChange: _util2.default.noop, // onChange回调
                    temp: null, // translate的缓存
                    bodyHeight: 5 * 48 // picker的高度,用于辅助点击滚动的计算
                }, options);
                var items = defaults.items.map(function (item) {
                    return '<div class="weui-picker__item' + (item.disabled ? ' weui-picker__item_disabled' : '') + '">' + ((typeof item === 'undefined' ? 'undefined' : _typeof(item)) == 'object' ? item.label : item) + '</div>';
                }).join('');
                var $this = (0, _util2.default)(this);

                $this.find('.weui-picker__content').html(items);

/*******************添加的内容:动态获取 weui-picker__item的高度*****************************/ if($this.find(".weui-picker__item").length > 0){ defaults.rowHeight = $this.find(".weui-picker__item")[0].offsetHeight; defaults.bodyHeight = $this.find(".weui-picker__item")[0].offsetHeight * 5; }
          /***************************************************************************************/ var $scrollable = $this.find(defaults.scrollable); // 可滚动的元素 var start = void 0; // 保存开始按下的位置 var end = void 0; // 保存结束时的位置 var startTime = void 0; // 开始触摸的时间 var translate = void 0; // 缓存 translate var points = []; // 记录移动点 // 首次触发选中事件 // 如果有缓存的选项,则用缓存的选项,否则使用中间值。 if (defaults.temp !== null && defaults.temp < defaults.items.length) { var index = defaults.temp; defaults.onChange.call(this, defaults.items[index], index); translate = (defaults.offset - index) * defaults.rowHeight; console.log("translate:"+translate); } else { var _index = getDefaultIndex(defaults.items); defaults.onChange.call(this, defaults.items[_index], _index); translate = getDefaultTranslate(defaults.offset, defaults.rowHeight, defaults.items); console.log("translate:"+translate); } setTranslate($scrollable, translate); var stop = function stop(diff) { translate += diff; // 移动到最接近的那一行 translate = Math.round(translate / defaults.rowHeight) * defaults.rowHeight; var max = getMax(defaults.offset, defaults.rowHeight); var min = getMin(defaults.offset, defaults.rowHeight, defaults.items.length); // 不要超过最大值或者最小值 if (translate > max) { translate = max; } if (translate < min) { translate = min; } // 如果是 disabled 的就跳过 var index = defaults.offset - translate / defaults.rowHeight; while (!!defaults.items[index] && defaults.items[index].disabled) { diff > 0 ? ++index : --index; } translate = (defaults.offset - index) * defaults.rowHeight; setTransition($scrollable, .3); setTranslate($scrollable, translate); // 触发选择事件 defaults.onChange.call(_this, defaults.items[index], index); }; function _start(pageY) { start = pageY; startTime = +new Date(); } function _move(pageY) { end = pageY; var diff = end - start; setTransition($scrollable, 0); setTranslate($scrollable, translate + diff); startTime = +new Date(); points.push({ time: startTime, y: end }); if (points.length > 40) { points.shift(); } } function _end(pageY) { if (!start) return; /** * 思路: * 0. touchstart 记录按下的点和时间 * 1. touchmove 移动时记录前 40个经过的点和时间 * 2. touchend 松开手时, 记录该点和时间. 如果松开手时的时间, 距离上一次 move时的时间超过 100ms, 那么认为停止了, 不执行惯性滑动 * 如果间隔时间在 100ms 内, 查找 100ms 内最近的那个点, 和松开手时的那个点, 计算距离和时间差, 算出速度 * 速度乘以惯性滑动的时间, 例如 300ms, 计算出应该滑动的距离 */ var endTime = new Date().getTime(); var relativeY = $this[0].getBoundingClientRect().top + defaults.bodyHeight / 2; end = pageY; // 如果上次时间距离松开手的时间超过 100ms, 则停止了, 没有惯性滑动 if (endTime - startTime > 100) { //如果end和start相差小于10,则视为 if (Math.abs(end - start) > 10) { stop(end - start); } else { stop(relativeY - end); } } else { if (Math.abs(end - start) > 10) { var endPos = points.length - 1; var startPos = endPos; for (var i = endPos; i > 0 && startTime - points[i].time < 100; i--) { startPos = i; } if (startPos !== endPos) { var ep = points[endPos]; var sp = points[startPos]; var t = ep.time - sp.time; var s = ep.y - sp.y; var v = s / t; // 出手时的速度 var diff = v * 150 + (end - start); // 滑行 150ms,这里直接影响“灵敏度” stop(diff); } else { stop(0); } } else { stop(relativeY - end); } } start = null; } /** * 因为现在没有移除匿名函数的方法,所以先暴力移除(offAll),并且改变$scrollable。 */ $scrollable = $this.offAll().on('touchstart', function (evt) { _start(evt.changedTouches[0].pageY); }).on('touchmove', function (evt) { _move(evt.changedTouches[0].pageY); evt.preventDefault(); }).on('touchend', function (evt) { _end(evt.changedTouches[0].pageY); }).find(defaults.scrollable); // 判断是否支持touch事件 https://github.com/Modernizr/Modernizr/blob/master/feature-detects/touchevents.js var isSupportTouch = 'ontouchstart' in window || window.DocumentTouch && document instanceof window.DocumentTouch; if (!isSupportTouch) { $this.on('mousedown', function (evt) { _start(evt.pageY); evt.stopPropagation(); evt.preventDefault(); }).on('mousemove', function (evt) { if (!start) return; _move(evt.pageY); evt.stopPropagation(); evt.preventDefault(); }).on('mouseup mouseleave', function (evt) { _end(evt.pageY); evt.stopPropagation(); evt.preventDefault(); }); } };

动态修改rowHeight,bodyHeight的高度:

if($this.find(".weui-picker__item").length > 0){
   defaults.rowHeight = $this.find(".weui-picker__item")[0].offsetHeight;
   defaults.bodyHeight = $this.find(".weui-picker__item")[0].offsetHeight * 5;
}

  

posted @ 2020-04-14 10:13  董七  阅读(934)  评论(0编辑  收藏  举报