基于 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, // 拖动区间下限
maxWidth: 0, // 拖动区间上限
sliderCallback: null, // 参数回调
node: [0, 25, 50, 75, 100], // 节点数及占比

// 初始化数据
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;
// 打开拖拽状态

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上拖拽结束时关闭可拖拽状态

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();
},
}
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, // 拖动区间下限
maxWidth: 0, // 拖动区间上限
sliderCallback: null, // 参数回调
node: [0, 25, 50, 75, 100], // 节点数及占比

// 初始化数据
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;
// 打开拖拽状态

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上拖拽结束时关闭可拖拽状态

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);
}
// 用的是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(),
getSlider: function () {

return m(slider, {

cb : function(arg){

console.log(arg,22222)

},
});
},

obj.getSlider(),说明一下说明一下因为公司项目涉及保密条例,电脑都加了安全限制,无法录制视频或者gif图片,所有只能截图展示了。效果效果可以点击圆点拖动,也可以直接点击灰条进行点选然后拖动,也可以点击灰条上的百分比圆点进行拖动,因为单独又把事件绑定到了body上,所以可以在灰条上拖动开始并且在组件外也可以进行拖动,类似Element UI的slider组件效果。
拖动参数的打印
只为分享写代码过程中的一些心得体会,感谢平台!以上就是本文的全部内容,希望对大家的学习有所帮助。