可拖拽組件slider.js使用方法詳解
基于 mithril.js ,javascript ,scss寫一個可拖動的滑塊組件,供大家參考,具體內容如下
問題描述:
需求需要實現一個可拖動的滑塊組件,但是又不能用UI框架,只好自己動手寫一個了。 廢話不多說,直接上代碼。
技術要求:
需要有mithril.js,javascript,scss技術基礎。
js及頁面代碼。
var m = require("mithril");
require('./slider.scss');
import slider from './slider';
let obj = {
colorWidth: 0, // 已拖拽長度
clickOpen: false, // 是否開啟拖拽
sliderDom: '', // 綁定的灰條dom
colorDom: '', // 綁定的有色條dom
radiusDom: '', // 綁定的圓點dom
moveEmentRect: null, // 獲取灰條dom參數
Percentage: 0, // 百分比
minWidth: 0, // 拖動區(qū)間下限
maxWidth: 0, // 拖動區(qū)間上限
sliderCallback: null, // 參數回調
node: [0, 25, 50, 75, 100], // 節(jié)點數及占比
// 初始化數據
initslider:function(){
obj.sliderDom = document.getElementsByClassName('slider-body')[0]; // 允許進行開始拖拽的元素
obj.colorDom = document.getElementsByClassName('slider-section')[0]; // 允許進行開始拖拽的元素
obj.radiusDom = document.getElementsByClassName('slider-radius-body')[0]; // 允許進行開始拖拽的元素
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;
}
},
// 鼠標點擊 拖動開始
getMousedown:function(e){
if (e.target === obj.sliderDom || e.target === obj.colorDom || e.target === obj.radiusDom) { // 判斷是否是可點擊拖拽的元素
obj.clickOpen = true; // 打開拖拽狀態(tài)
let Width = e.clientX - obj.moveEmentRect.left; // 計算拖拽距離
obj.colorWidth = this.handleWidth(Width); // 處理拖拽距離轉化為長度
console.log(obj.colorWidth, '拖動開始')
this.sliderCallback && this.sliderCallback({
colorWidth : this.getPercentage(), // 將數據回傳頁面
})
}
},
// 拖動中
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(), // 將數據回傳頁面
})
}
},
// 鼠標松開 拖動結束
getmouseUp:function(){
obj.clickOpen = false;
console.log('拖動結束')
},
// 綁定到body上,實現在組件外面可以拖拽
getBodyMouse: function(){
let body = document.querySelector('body');
body.onmousemove = function(e){
obj.getMoveWidth(e); // 在body上拖拽組件
};
body.onmouseup = function(e){
obj.getmouseUp(e); // 在body上拖拽結束時關閉可拖拽狀態(tài)
obj.onmouseout(); // 在body上結束拖拽時隱藏百分比
}
},
// 計算拖動的百分比
getPercentage: function () {
let _P = (Number(obj.colorWidth) / Number(obj.maxWidth)).toFixed(2);
this.Percentage = Math.floor((Number(_P || 0) * 100));
return Number(_P);
},
// 鼠標移入顯示百分比
onmouseover:function(){
let _S = document.getElementsByClassName('slider-percentage')[0];
_S.style.display = 'block';
},
// 鼠標移除隱藏百分比
onmouseout:function(){
let _S = document.getElementsByClassName('slider-percentage')[0];
_S.style.display = 'none';
},
// 清除數據
closemode: function () {
obj.colorWidth = 0; // 已拖拽長度
obj.clickOpen = false; // 是否開啟拖拽
obj.sliderDom = ''; // 綁定的灰條dom
obj.colorDom = ''; // 綁定的有色條dom
obj.radiusDom = ''; // 綁定的圓點dom
obj.moveEmentRect = null; // 獲取灰條dom參數
obj.Percentage = 0; // 百分比
obj.minWidth = 0;
obj.maxWidth = 0;
obj.sliderCallback = null; // 參數回調
},
// 百分比選擇
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(), // 將數據回傳頁面
});
},
}
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預處理樣式
// $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);
}
調用
getSlider: function () {
return m(slider, {
cb : function(arg){
console.log(arg,22222)
},
});
},
obj.getSlider(),
說明一下
因為公司項目涉及保密條例,電腦都加了安全限制,無法錄制視頻或者gif圖片,所有只能截圖展示了。
效果
可以點擊圓點拖動,也可以直接點擊灰條進行點選然后拖動,也可以點擊灰條上的百分比圓點進行拖動,因為單獨又把事件綁定到了body上,所以可以在灰條上拖動開始并且在組件外也可以進行拖動,類似Element UI的slider組件效果。


拖動參數的打印


只為分享寫代碼過程中的一些心得體會,感謝平臺!
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
輕松玩轉BootstrapTable(后端使用SpringMVC+Hibernate)
這篇文章主要和大家輕松玩轉BootstrapTable,后端使用SpringMVC+Hibernate,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-09-09
一道優(yōu)雅面試題分析js中fn()和return fn()的區(qū)別
這篇文章主要帶領大家深入理解JavaScript中 fn() 和 return fn() 的區(qū)別,感興趣的小伙伴們可以參考一下2016-07-07

