可拖拽组件slider.js使用方法详解


Posted in Javascript onDecember 04, 2020

基于 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();
 },
 }

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组件效果。

可拖拽组件slider.js使用方法详解
可拖拽组件slider.js使用方法详解

拖动参数的打印

可拖拽组件slider.js使用方法详解
可拖拽组件slider.js使用方法详解

只为分享写代码过程中的一些心得体会,感谢平台!

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JavaScript对象模型-执行模型
Apr 28 Javascript
js使用eval解析json实例与注意事项分享
Jan 18 Javascript
JavaScript控制按钮可用或不可用的方法
Apr 03 Javascript
不能不知道的10个angularjs英文学习网站
Mar 23 Javascript
AngularJS基础 ng-readonly 指令简单示例
Aug 02 Javascript
微信JS-SDK自定义分享功能实例详解【分享给朋友/分享到朋友圈】
Nov 25 Javascript
JQuery Ajax 异步操作之动态添加节点功能
May 24 jQuery
详解如何使用webpack打包多页jquery项目
Feb 01 jQuery
使用imba.io框架得到比 vue 快50倍的性能基准
Jun 17 Javascript
微信小程序绘制图片发送朋友圈
Jul 25 Javascript
使用JavaScript计算前一天和后一天的思路详解
Dec 20 Javascript
在vant中使用时间选择器和popup弹出层的操作
Nov 04 Javascript
js实现复制粘贴的两种方法
Dec 04 #Javascript
echarts浮动显示单位的实现方法示例
Dec 04 #Javascript
JavaScript中条件语句的优化技巧总结
Dec 04 #Javascript
三剑客:offset、client和scroll还傻傻分不清?
Dec 04 #Javascript
简单谈谈offsetleft、offsetTop和offsetParent
Dec 04 #Javascript
HTML元素拖拽功能实现的完整实例
Dec 04 #Javascript
解决Vue-cli3没有vue.config.js文件夹及配置vue项目域名的问题
Dec 04 #Vue.js
You might like
PHP通用检测函数集合
2011/02/08 PHP
PHP 中检查或过滤IP地址的实现代码
2011/11/27 PHP
IIS6.0中配置php服务全过程解析
2013/08/07 PHP
深入解析PHP的Laravel框架中的event事件操作
2016/03/21 PHP
PHPExcel实现的读取多工作表操作示例
2020/04/14 PHP
Enter转换为Tab的小例子(兼容IE,Firefox)
2013/11/14 Javascript
js获取通过ajax返回的map型的JSONArray的方法
2014/01/09 Javascript
JS父页面与子页面相互传值方法
2014/03/05 Javascript
JS常用表单验证方法总结
2014/05/22 Javascript
javascript实现页面刷新时自动清空表单并选中的方法
2015/07/18 Javascript
推荐10 个很棒的 jQuery 特效代码
2015/10/04 Javascript
基于JavaScript如何制作遮罩层对话框
2016/01/26 Javascript
Vue实现双向绑定的方法
2016/12/22 Javascript
vue.js的提示组件
2017/03/02 Javascript
解决Node.js使用MySQL出现connect ECONNREFUSED 127.0.0.1:3306的问题
2017/03/09 Javascript
在Vue中如何使用Cookie操作实例
2017/07/27 Javascript
Vue Cli与BootStrap结合实现表格分页功能
2017/08/18 Javascript
mpvue 页面预加载新增preLoad生命周期的两种方式
2019/10/17 Javascript
vue-路由精讲 二级路由和三级路由的作用
2020/08/06 Javascript
python通过zlib实现压缩与解压字符串的方法
2014/11/19 Python
Python中对元组和列表按条件进行排序的方法示例
2015/11/10 Python
PyCharm+Qt Designer+PyUIC安装配置教程详解
2019/06/13 Python
利用Python实现Shp格式向GeoJSON的转换方法
2019/07/09 Python
程序员的七夕用30行代码让Python化身表白神器
2019/08/07 Python
Python values()与itervalues()的用法详解
2019/11/27 Python
git查看、创建、删除、本地、远程分支方法详解
2020/02/18 Python
AUC计算方法与Python实现代码
2020/02/28 Python
Python logging模块进行封装实现原理解析
2020/08/07 Python
全球速卖通法国在线交易平台:AliExpress法国
2017/07/07 全球购物
ESDlife健康生活易:身体检查预订、搜寻及比较
2019/05/10 全球购物
介绍一些UNIX常用简单命令
2014/11/11 面试题
校园文化标语
2014/06/18 职场文书
单位同意报考证明
2015/06/17 职场文书
初中物理教学反思
2016/02/19 职场文书
MySql存储过程之逻辑判断和条件控制
2021/05/26 MySQL
Window server中安装Redis的超详细教程
2021/11/17 Redis