在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; }