可拖拽組件slider.js使用方法詳解
基于 mithril.js ,javascript ,scss寫一個可拖動的滑塊組件,供大家參考,具體內(nèi)容如下
問題描述:
需求需要實現(xiàn)一個可拖動的滑塊組件,但是又不能用UI框架,只好自己動手寫一個了。 廢話不多說,直接上代碼。
技術(shù)要求:
需要有mithril.js,javascript,scss技術(shù)基礎(chǔ)。
js及頁面代碼。
var m = require("mithril"); require('./slider.scss'); import slider from './slider'; let obj = { colorWidth: 0, // 已拖拽長度 clickOpen: false, // 是否開啟拖拽 sliderDom: '', // 綁定的灰條dom colorDom: '', // 綁定的有色條dom radiusDom: '', // 綁定的圓點(diǎn)dom moveEmentRect: null, // 獲取灰條dom參數(shù) Percentage: 0, // 百分比 minWidth: 0, // 拖動區(qū)間下限 maxWidth: 0, // 拖動區(qū)間上限 sliderCallback: null, // 參數(shù)回調(diào) node: [0, 25, 50, 75, 100], // 節(jié)點(diǎn)數(shù)及占比 // 初始化數(shù)據(jù) initslider:function(){ obj.sliderDom = document.getElementsByClassName('slider-body')[0]; // 允許進(jìn)行開始拖拽的元素 obj.colorDom = document.getElementsByClassName('slider-section')[0]; // 允許進(jìn)行開始拖拽的元素 obj.radiusDom = document.getElementsByClassName('slider-radius-body')[0]; // 允許進(jìn)行開始拖拽的元素 obj.moveEmentRect = obj.sliderDom.getBoundingClientRect(); // 獲取拖拽父元素的寬度 obj.maxWidth = obj.moveEmentRect.width; }, // 處理寬度值域 handleWidth:function(EV){ if (EV <= obj.minWidth) { return obj.minWidth; } else if (EV >= obj.maxWidth) { return obj.maxWidth; } else { return EV; } }, // 鼠標(biāo)點(diǎn)擊 拖動開始 getMousedown:function(e){ if (e.target === obj.sliderDom || e.target === obj.colorDom || e.target === obj.radiusDom) { // 判斷是否是可點(diǎn)擊拖拽的元素 obj.clickOpen = true; // 打開拖拽狀態(tài) let Width = e.clientX - obj.moveEmentRect.left; // 計算拖拽距離 obj.colorWidth = this.handleWidth(Width); // 處理拖拽距離轉(zhuǎn)化為長度 console.log(obj.colorWidth, '拖動開始') this.sliderCallback && this.sliderCallback({ colorWidth : this.getPercentage(), // 將數(shù)據(jù)回傳頁面 }) } }, // 拖動中 getMoveWidth:function(e){ if (obj.clickOpen) { let moveX = e.clientX - obj.moveEmentRect.left; obj.colorWidth = this.handleWidth(moveX); console.log(obj.colorWidth, '拖動中') this.sliderCallback && this.sliderCallback({ colorWidth : this.getPercentage(), // 將數(shù)據(jù)回傳頁面 }) } }, // 鼠標(biāo)松開 拖動結(jié)束 getmouseUp:function(){ obj.clickOpen = false; console.log('拖動結(jié)束') }, // 綁定到body上,實現(xiàn)在組件外面可以拖拽 getBodyMouse: function(){ let body = document.querySelector('body'); body.onmousemove = function(e){ obj.getMoveWidth(e); // 在body上拖拽組件 }; body.onmouseup = function(e){ obj.getmouseUp(e); // 在body上拖拽結(jié)束時關(guān)閉可拖拽狀態(tài) obj.onmouseout(); // 在body上結(jié)束拖拽時隱藏百分比 } }, // 計算拖動的百分比 getPercentage: function () { let _P = (Number(obj.colorWidth) / Number(obj.maxWidth)).toFixed(2); this.Percentage = Math.floor((Number(_P || 0) * 100)); return Number(_P); }, // 鼠標(biāo)移入顯示百分比 onmouseover:function(){ let _S = document.getElementsByClassName('slider-percentage')[0]; _S.style.display = 'block'; }, // 鼠標(biāo)移除隱藏百分比 onmouseout:function(){ let _S = document.getElementsByClassName('slider-percentage')[0]; _S.style.display = 'none'; }, // 清除數(shù)據(jù) closemode: function () { obj.colorWidth = 0; // 已拖拽長度 obj.clickOpen = false; // 是否開啟拖拽 obj.sliderDom = ''; // 綁定的灰條dom obj.colorDom = ''; // 綁定的有色條dom obj.radiusDom = ''; // 綁定的圓點(diǎn)dom obj.moveEmentRect = null; // 獲取灰條dom參數(shù) obj.Percentage = 0; // 百分比 obj.minWidth = 0; obj.maxWidth = 0; obj.sliderCallback = null; // 參數(shù)回調(diào) }, // 百分比選擇 getNodePer:function () { return obj.node.map((item) => { return m('div',{class:'slider-node', style: `left: ${item}%`, onclick: function(){ obj.getNodeData(item); }},[ ]) }) }, getNodeData:function(item){ obj.colorWidth = Number(obj.maxWidth) * (item / 100); this.sliderCallback && this.sliderCallback({ colorWidth : this.getPercentage(), // 將數(shù)據(jù)回傳頁面 }); }, } export default { oninit: function (vnode) { }, oncreate: function (vnode) { obj.sliderCallback = vnode.attrs.cb; obj.initslider(); obj.onmouseout(); obj.getBodyMouse(); }, view: function (vnode) { return m('div', {class: 'slider'}, [ m('div',{class:"slider-body",onmousedown:function(e){ obj.getMousedown(e); },onmousemove:function(e){ obj.getMoveWidth(e); },onmouseup:function(e){ obj.getmouseUp(e); }},[ m('div',{class:"slider-section", style:`width: ${obj.colorWidth}px`},[ m('div',{class:"slider-radius",onmouseover:function(){ obj.onmouseover(); },onmouseout:function(){ obj.onmouseout(); }},[ m('div',{class:"slider-radius-body"},[]) ]), m('div',{class:"slider-percentage" , style: `left: ${obj.colorWidth - 25}px`},[ obj.Percentage + '%' ]), ]), obj.getNodePer(), ]), ]) }, onremove: function (vnode) { obj.closemode(); }, }
scss樣式代碼。
// 用的是scss預(yù)處理樣式 // $arrowsSize scss變量 // var(--primary-lighten)用的是全局顏色,可以直接用顏色值代替 // $dark #ligth 為黑夜白天樣式,可以不用。 $arrowsSize: 6px; // 三角形 大小 .slider{ width: 100%; .slider-body{ width: 100%; height: 6px; margin: 16px 0; border-radius: 5px; position: relative; cursor: pointer; .slider-section{ height: 6px; background-color: var(--primary-lighten); // width: 30%; position: absolute; left: 0; border-radius: 5px; .slider-radius{ height: 16px; width: 16px; position: absolute; left: 100%; z-index: 999; top: -5px; transform: translateX(-50%); background-color: transparent; text-align: center; user-select: none; line-height: normal; .slider-radius-body{ width: 16px; height: 16px; border: 2px solid var(--primary-lighten); background-color: var(--fontwhite-base); border-radius: 50%; transition: .2s; user-select: none; &::after { content: ''; height: 100%; display: inline-block; vertical-align: middle; } } } .slider-percentage{ // display: none; height: 25px; width: 50px; line-height: 25px; border-radius: 5px; background-color: var(--mode-darken); text-align: center; font-size: 14px; color: var(--font-darken); position: absolute; top: -40px; // left: 100%; &::after { content: ''; display: inline-block; vertical-align: middle; width: 0; height: 0; position: absolute; border-top: solid $arrowsSize; border-left: solid $arrowsSize transparent !important; border-right: solid $arrowsSize transparent !important; border-bottom: solid $arrowsSize transparent !important; top: 25px; left: 35%; color: var(--mode-darken); } } } .slider-node{ position: absolute; height: 8px; width: 8px; border-radius: 100%; background-color: var(--fontwhite-base); border: 2px solid var(--primary-lighten); transform: translateX(-50%); top: -1px; } } } #dark .slider-body{ background-color: var(--line-darken3); } #light .slider-body{ background-color: var(--line-lighten3); }
調(diào)用
getSlider: function () { return m(slider, { cb : function(arg){ console.log(arg,22222) }, }); }, obj.getSlider(),
說明一下
因為公司項目涉及保密條例,電腦都加了安全限制,無法錄制視頻或者gif圖片,所有只能截圖展示了。
效果
可以點(diǎn)擊圓點(diǎn)拖動,也可以直接點(diǎn)擊灰條進(jìn)行點(diǎn)選然后拖動,也可以點(diǎn)擊灰條上的百分比圓點(diǎn)進(jìn)行拖動,因為單獨(dú)又把事件綁定到了body上,所以可以在灰條上拖動開始并且在組件外也可以進(jìn)行拖動,類似Element UI的slider組件效果。
拖動參數(shù)的打印
只為分享寫代碼過程中的一些心得體會,感謝平臺!
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
輕松玩轉(zhuǎn)BootstrapTable(后端使用SpringMVC+Hibernate)
這篇文章主要和大家輕松玩轉(zhuǎn)BootstrapTable,后端使用SpringMVC+Hibernate,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-09-09一道優(yōu)雅面試題分析js中fn()和return fn()的區(qū)別
這篇文章主要帶領(lǐng)大家深入理解JavaScript中 fn() 和 return fn() 的區(qū)別,感興趣的小伙伴們可以參考一下2016-07-07利用javascript如何隨機(jī)生成一定位數(shù)的密碼
這篇文章主要給大家介紹了關(guān)于利用javascript如何隨機(jī)生成一定位數(shù)的密碼的相關(guān)資料,文中給出了詳細(xì)的示例代碼,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2017-09-09