UNPKG

5.39 kBJavaScriptView Raw
1import { r as registerInstance, c as createEvent, h, H as Host, g as getElement } from './index-8809c729.js';
2
3let Slider = class {
4 constructor(hostRef) {
5 registerInstance(this, hostRef);
6 this.onChange = createEvent(this, "change", 7);
7 this.onChanging = createEvent(this, "changing", 7);
8 this.min = 0;
9 this.max = 100;
10 this.step = 1;
11 this.disabled = false;
12 this.value = 0;
13 this.activeColor = '#1aad19';
14 this.backgroundColor = '#e9e9e9';
15 this.blockSize = 28;
16 this.blockColor = '#ffffff';
17 this.showValue = false;
18 this.name = '';
19 this.totalWidth = 0;
20 this.touching = false;
21 this.ogX = 0;
22 this.touchId = null;
23 this.percent = 0;
24 this.isWillLoadCalled = false;
25 this.handleTouchStart = (e) => {
26 if (this.touching || this.disabled)
27 return;
28 this.touching = true;
29 this.touchId = e.targetTouches[0].identifier;
30 this.totalWidth = this.sliderInsRef.clientWidth;
31 this.ogX = e.targetTouches[0].pageX;
32 this.ogPercent = this.percent;
33 };
34 this.handleTouchMove = (e) => {
35 const { disabled, touching, touchId, totalWidth, max, min, ogX, ogPercent } = this;
36 if (!touching || disabled)
37 return;
38 if (e.targetTouches[0].identifier !== touchId)
39 return;
40 // 阻止默认事件
41 e.preventDefault();
42 const pageX = e.targetTouches[0].pageX;
43 const diffX = pageX - ogX;
44 let percent = diffX / totalWidth * 100 + ogPercent;
45 percent = Math.max(0, Math.min(percent, 100));
46 const val = min + percent * 0.01 * (max - min);
47 this.updateByStep(val);
48 this.onChanging.emit({
49 detail: e.detail,
50 value: this.val
51 });
52 };
53 this.handleTouchEnd = (e) => {
54 const { disabled, touching } = this;
55 if (!touching || disabled)
56 return;
57 if (this.percent !== this.ogPercent) {
58 this.onChange.emit({
59 detail: e.detail,
60 value: this.val
61 });
62 }
63 this.touching = false;
64 this.touchId = null;
65 this.ogX = 0;
66 this.ogPercent = 0;
67 };
68 }
69 function(newVal) {
70 if (!this.isWillLoadCalled)
71 return;
72 const { max, min } = this;
73 if (newVal !== null && newVal !== this.val) {
74 const val = Math.max(min, Math.min(newVal, max));
75 this.updateByStep(val);
76 }
77 }
78 componentDidLoad() {
79 Object.defineProperty(this.el, 'value', {
80 get: () => this.val,
81 set: value => (this.value = value),
82 configurable: true
83 });
84 // 在自动化测试时,如果通过 JSX 绑定 touch 事件,
85 // 模拟的 touch 事件只会在浏览器的 device mode 下触发,Karma 跑的测试就会跪。
86 // 因此改为 didLoad 后 addEventListener 的形式。
87 this.handler.addEventListener('touchstart', this.handleTouchStart);
88 this.handler.addEventListener('touchmove', this.handleTouchMove);
89 this.handler.addEventListener('touchend', this.handleTouchEnd);
90 }
91 componentDidUpdate() {
92 this.value = null;
93 }
94 componentWillLoad() {
95 this.isWillLoadCalled = true;
96 const { value, max, min } = this;
97 if (value === null)
98 return;
99 const val = Math.max(min, Math.min(value, max));
100 this.updateByStep(val);
101 }
102 // 根据步长 step 修改 value
103 updateByStep(value) {
104 const { max, min, step } = this;
105 const steps = Math.floor((max - min) / step);
106 for (let i = 0; i <= steps; i++) {
107 const current = min + step * i;
108 const next = i === steps ? null : min + step * (i + 1);
109 if (value === current)
110 break;
111 if (!next && value > current) {
112 // step 不能被 max - min 整除
113 value = current;
114 }
115 if (next && value > current && value < next) {
116 if (value - current < step / 2) {
117 value = current;
118 }
119 else {
120 value = next;
121 }
122 break;
123 }
124 }
125 const percent = (value - min) / (max - min) * 100;
126 this.val = value;
127 this.percent = percent;
128 }
129 render() {
130 const { showValue, backgroundColor, activeColor, blockColor, name, percent, val } = this;
131 let blockSize = this.blockSize;
132 const innerStyles = { backgroundColor };
133 const percentage = percent > 100 ? 100 : percent;
134 const trackStyles = {
135 width: `${percentage}%`,
136 backgroundColor: activeColor
137 };
138 if (blockSize < 12) {
139 blockSize = 12;
140 }
141 if (blockSize > 28) {
142 blockSize = 28;
143 }
144 const handlerStyles = {
145 left: `${percentage}%`,
146 width: `${blockSize}px`,
147 height: `${blockSize}px`,
148 backgroundColor: blockColor,
149 marginTop: `-${Math.floor(blockSize / 2)}px`,
150 marginLeft: `-${Math.floor(blockSize / 2)}px`
151 };
152 return (h(Host, { class: 'weui-slider-box' }, h("div", { class: 'weui-slider' }, h("div", { class: 'weui-slider__inner', style: innerStyles, ref: c => (this.sliderInsRef = c) }, h("div", { style: trackStyles, class: 'weui-slider__track' }), h("div", { class: 'weui-slider__handler', ref: dom => {
153 if (dom)
154 this.handler = dom;
155 }, style: handlerStyles }), h("input", { type: 'hidden', name: name, value: val }))), showValue && h("div", { class: 'weui-slider-box__value' }, val)));
156 }
157 get el() { return getElement(this); }
158 static get watchers() { return {
159 "value": ["function"]
160 }; }
161};
162
163export { Slider as taro_slider_core };