咱們先來看一張圖片: git
要實現這樣的效果咱們有不少種方法,好比直接使用<input type="range" />
修改樣式便可,也可用下面的這種方式修改 樣式
HTML代碼:github
<div class="slider"> <button class="slider-track"></button> <button class="slider-thumb"></button> </div>
CSS 樣式:app
.slider { padding: 5px 0; position: relative; margin: 30px 10%; --percent: 0; } .slider-track { display: block; width: 100%; height: 6px; background-color: lightgray; border: 0; padding: 0; } .slider-track::before { content: ''; display: block; height: 100%; background-color: skyblue; width: calc(1% * var(--percent)); } .slider-thumb { position: absolute; width: 16px; height: 16px; border: 0; padding: 0; background: #fff; box-shadow: 0 0 0 1px skyblue; border-radius: 50%; left: calc(1% * var(--percent)); top: 0; margin: auto -8px; }`
那如何以組件的形式生成一個簡單的滑塊呢?ide
JS代碼以下:測試
class Slider { constructor(opts = {}) { this.el = opts.el; this.value = opts.value || 0; this.slider = null; this.render(); this.bindEvt(); return { val: (value) => { this.val(value); } } } //渲染DOM render() { const container = document.querySelector(this.el); const slider = document.createElement('div'); this.slider = slider; // 有缺省值則賦值 if (this.value) { this.val(this.value); } slider.className = "slider"; // 軌道無需獲取焦點 slider.innerHTML = ( `<button class="slider-track" tabindex="-1"></button> <button class="slider-thumb"></button>` ); if (container) { container.appendChild(slider); } else { // 若未指定容器,則在 body 標籤最後插入 DOM 結構 document.body.appendChild(slider); } } // 監聽事件 bindEvt() { const {slider} = this; const slider_track = slider.querySelector('.slider-track'); const slider_thumb = slider.querySelector('.slider-thumb'); let readymMove = false; const startHandle = e => { if (e.target === slider_thumb) { e.stopPropagation(); readymMove = true; } } const moveHandle = e => { if (readymMove) { this.computeVal(e); } } const endHandle = () => { readymMove = false }; slider.addEventListener('click', e => { if (e.target == slider_track) { this.computeVal(e); } }, false) slider.addEventListener('keydown', evt => { if (document.activeElement === slider_thumb) { let value = this.val(); evt = (evt) ? evt : ((window.event) ? window.event : ""); //兼容IE和Firefox得到keyBoardEvent對象 var keyCode = evt.keyCode ? evt.keyCode : evt.which; //兼容IE和Firefox得到keyBoardEvent對象的鍵值 switch (keyCode) { //左箭頭 case 37: value--; break; //右箭頭 case 39: value++; break; } } this.val(value); }, false) // 開始拖動 slider.addEventListener('touchstart', startHandle); slider.addEventListener('mousedown', startHandle); // 拖動中 window.addEventListener('touchmove', moveHandle); window.addEventListener('mousemove', moveHandle); // 拖動結束 window.addEventListener('touchend', endHandle); window.addEventListener('mouseup', endHandle); } // 計算當前值 computeVal(e) { const {width, left} = this.slider.getBoundingClientRect(); let posX = e.pageX; if (e.touches) { // 兼容移動端 posx = e.touches[0].pageX; } this.val((posX - left) / width * 100); } // 賦值 & 取值 val(value) { if (typeof value === 'undefined') { // 返回當前 slider 的 percent 值 return this.slider.style.getPropertyValue('--percent').trim() || 0; } if (isNaN(value)) { // 過濾非法字符 return; } if (value < 0) { value = 0; } else if (value > 100) { value = 1000; } this.slider.style.setProperty('--percent', value); } }
使用方式:ui
let myslider1 = new Slider({ el: '#box' }); // 指定容器 new Slider({ value: 50 }); // 缺省賦值 myslider1.val(value); // js 動態賦值 or new Slider(); // 無參數(插入到 body 標籤最後,賦值爲 0)
代碼實現仍是很簡單的,有興趣的能夠點這裏,更多基礎測試等着你this