UNPKG

@tarojs/components

Version:
166 lines (160 loc) 6.03 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); const index = require('./index-a7069008.js'); const indexCss = ".weui-slider{user-select:none;padding:15px 18px}.weui-slider__inner{background-color:#e9e9e9;height:2px;position:relative}.weui-slider__track{background-color:#1aad19;width:0;height:2px}.weui-slider__handler{background-color:#fff;border-radius:50%;width:28px;height:28px;margin-top:-14px;margin-left:-14px;position:absolute;top:50%;left:0;box-shadow:0 0 4px rgba(0,0,0,.2)}.weui-slider-box{align-items:center;display:flex}.weui-slider-box .weui-slider{flex:1}.weui-slider-box__value{color:#888;text-align:center;min-width:24px;margin-left:.5em;font-size:14px}"; const Slider = class { constructor(hostRef) { index.registerInstance(this, hostRef); this.onChange = index.createEvent(this, "change", 7); this.onChanging = index.createEvent(this, "changing", 7); this.handleTouchStart = (e) => { if (this.touching || this.disabled) return; this.touching = true; this.touchId = e.targetTouches[0].identifier; this.totalWidth = this.sliderInsRef.clientWidth || 1; this.ogX = e.targetTouches[0].pageX; this.ogPercent = this.percent; }; this.handleTouchMove = (e) => { const { disabled, touching, touchId, totalWidth, max, min, ogX, ogPercent } = this; if (!touching || disabled) return; if (e.targetTouches[0].identifier !== touchId) return; // 阻止默认事件 e.preventDefault(); const pageX = e.targetTouches[0].pageX; const diffX = pageX - ogX; let percent = diffX / totalWidth * 100 + ogPercent; percent = this.handleValueUpdate(percent, 0, 100); const val = min + percent * 0.01 * (max - min); this.updateByStep(val); this.onChanging.emit({ detail: e.detail, value: this.value }); }; this.handleTouchEnd = (e) => { const { disabled, touching } = this; if (!touching || disabled) return; if (this.percent !== this.ogPercent) { this.onChange.emit({ detail: e.detail, value: this.value }); } this.touching = false; this.touchId = null; this.ogX = 0; this.ogPercent = 0; }; this.handleValueUpdate = (e, min = this.min, max = this.max) => { e = isNaN(e) ? 0 : e; return Math.max(min, Math.min(e, max)); }; this.min = 0; this.max = 100; this.step = 1; this.disabled = false; this.value = 0; this.activeColor = '#1aad19'; this.backgroundColor = '#e9e9e9'; this.blockSize = 28; this.blockColor = '#ffffff'; this.showValue = false; this.name = ''; this.totalWidth = 1; this.touching = false; this.ogX = 0; this.touchId = null; this.percent = 0; this.ogPercent = undefined; this.isWillLoadCalled = false; } function(value) { if (!this.isWillLoadCalled) return; const { max, min } = this; if (value !== null) { const val = this.handleValueUpdate(value, min, max); this.updateByStep(val); } } componentDidLoad() { // 在自动化测试时,如果通过 JSX 绑定 touch 事件, // 模拟的 touch 事件只会在浏览器的 device mode 下触发,Karma 跑的测试就会跪。 // 因此改为 didLoad 后 addEventListener 的形式。 this.handler.addEventListener('touchstart', this.handleTouchStart); this.handler.addEventListener('touchmove', this.handleTouchMove); this.handler.addEventListener('touchend', this.handleTouchEnd); } componentWillLoad() { this.isWillLoadCalled = true; const { value, max, min } = this; const val = this.handleValueUpdate(value, min, max); this.updateByStep(val); } // 根据步长 step 修改 value updateByStep(value) { const { max, min, step } = this; const steps = Math.floor((max - min) / step); for (let i = 0; i <= steps; i++) { const current = min + step * i; const next = i === steps ? null : min + step * (i + 1); if (value === current) break; if (!next && value > current) { // step 不能被 max - min 整除 value = current; } if (next && value > current && value < next) { if (value - current < step / 2) { value = current; } else { value = next; } break; } } const percent = (value - min) / (max - min) * 100; this.value = value; this.percent = percent; } render() { const { showValue, backgroundColor, activeColor, blockColor, name, percent, value } = this; let blockSize = this.blockSize; const innerStyles = { backgroundColor }; const percentage = percent > 100 ? 100 : percent; const trackStyles = { width: `${percentage}%`, backgroundColor: activeColor }; if (blockSize < 12) { blockSize = 12; } if (blockSize > 28) { blockSize = 28; } const handlerStyles = { left: `${percentage}%`, width: `${blockSize}px`, height: `${blockSize}px`, backgroundColor: blockColor, marginTop: `-${Math.floor(blockSize / 2)}px`, marginLeft: `-${Math.floor(blockSize / 2)}px` }; return (index.h(index.Host, { class: 'weui-slider-box' }, index.h("div", { class: 'weui-slider' }, index.h("div", { class: 'weui-slider__inner', style: innerStyles, ref: c => (this.sliderInsRef = c) }, index.h("div", { style: trackStyles, class: 'weui-slider__track' }), index.h("div", { class: 'weui-slider__handler', ref: dom => { if (dom) this.handler = dom; }, style: handlerStyles }), index.h("input", { type: 'hidden', name: name, value: value }))), showValue && index.h("div", { class: 'weui-slider-box__value' }, value))); } get el() { return index.getElement(this); } static get watchers() { return { "value": ["function"] }; } }; Slider.style = indexCss; exports.taro_slider_core = Slider;