可拖拽组件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中的prototype属性实例分析说明
Aug 09 Javascript
推荐10个超棒的jQuery工具提示插件
Oct 11 Javascript
关于在IE下的一个安全BUG --可用于跟踪用户的系统鼠标位置
Apr 17 Javascript
js借助ActiveXObject实现创建文件
Sep 29 Javascript
用js来刷新当前页面保留参数的具体实现
Dec 23 Javascript
浅谈使用splice函数对数组中的元素进行删除时的注意事项
Dec 04 Javascript
jquery仿苹果的时间/日期选择效果
Mar 08 Javascript
详解如何在react中搭建d3力导向图
Jan 12 Javascript
Vue中的情侣属性$dispatch和$broadcast详解
Mar 07 Javascript
Angular2使用SVG自定义图表(条形图、折线图)组件示例
May 10 Javascript
vue 使用高德地图vue-amap组件过程解析
Sep 07 Javascript
Vue实现简单的留言板
Oct 23 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
一个简单的自动发送邮件系统(一)
2006/10/09 PHP
PHP中for循环语句的几种变型
2007/03/16 PHP
几个有用的php字符串过滤,转换函数代码
2012/05/01 PHP
关于URL最大长度限制的相关资料查证
2014/12/23 PHP
Laravel 框架路由原理与路由访问实例分析
2020/04/14 PHP
百度留言本js 大家可以参考下
2009/10/13 Javascript
JQuery 绑定select标签的onchange事件,弹出选择的值,并实现跳转、传参
2011/01/06 Javascript
基于jquery实现点击左右按钮图片横向滚动
2013/04/11 Javascript
JavaScript中把数字转换为字符串的程序代码
2013/06/19 Javascript
让元素在网页中可拖动示例代码
2013/08/13 Javascript
JS实现拖动示例代码
2013/11/01 Javascript
jQuery对象初始化的传参方式
2015/02/26 Javascript
JavaScript实现图片DIV竖向滑动的方法
2015/04/25 Javascript
简介JavaScript中用于处理正切的Math.tan()方法
2015/06/15 Javascript
使用jquery/js获取iframe父子级、同级获取元素的方法
2016/08/05 Javascript
浅谈Vue2.4.0 $attrs与inheritAttrs的具体使用
2020/03/08 Javascript
vue 避免变量赋值后双向绑定的操作
2020/11/07 Javascript
JavaScript 如何在浏览器中使用摄像头
2020/12/02 Javascript
Angular处理未可知异常错误的方法详解
2021/01/17 Javascript
js canvas实现五子棋小游戏
2021/01/22 Javascript
Python+Selenium自动化实现分页(pagination)处理
2017/03/31 Python
Python qqbot 实现qq机器人的示例代码
2019/07/11 Python
python 实现GUI(图形用户界面)编程详解
2019/07/17 Python
详解用python计算阶乘的几种方法
2019/08/14 Python
python音频处理的示例详解
2020/12/23 Python
Waterford英国官方网站:世界上最受欢迎的优质水晶品牌
2019/08/17 全球购物
Abbott Lyon官网:女士手表、珠宝及配件
2020/12/26 全球购物
php优化查询foreach代码实例讲解
2021/03/24 PHP
护士自荐信范文
2013/12/15 职场文书
学校运动会开幕演讲稿
2014/01/04 职场文书
单位未婚证明范本
2014/01/18 职场文书
环保倡议书格式范文
2014/05/14 职场文书
乡镇党的群众路线教育实践活动个人对照检查材料
2014/09/23 职场文书
思想作风建设心得体会
2014/10/22 职场文书
父母教会我观后感
2015/06/17 职场文书
开业庆典致辞
2015/08/01 职场文书