可拖拽组件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 相关文章推荐
风吟的小型JavaScirpt库 (FY.JS).
Mar 09 Javascript
详解javascript跨浏览器事件处理程序
Mar 27 Javascript
原生js仿jquery一些常用方法(必看篇)
Sep 20 Javascript
微信小程序 wx.request(object) API详解及实例代码
Sep 30 Javascript
微信小程序 Windows2008 R2服务器配置TLS1.2方法
Dec 05 Javascript
jQuery中页面返回顶部的方法总结
Dec 30 Javascript
JS字符串false转boolean的方法(推荐)
Mar 08 Javascript
JS实现匀速与减速缓慢运动的动画效果封装示例
Aug 27 Javascript
JS原生瀑布流效果实现
Apr 26 Javascript
React+TypeScript+webpack4多入口配置详解
Aug 08 Javascript
Vue实现移动端拖拽交换位置
Jul 29 Javascript
jquery插件实现轮播图效果
Oct 19 jQuery
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分割合并两个字符串的函数实例
2015/06/19 PHP
PHP中header用法小结
2016/05/23 PHP
php查询及多条件查询
2017/02/26 PHP
PHP设计模式之装饰器模式实例详解
2018/02/07 PHP
php post换行的方法
2020/02/03 PHP
jquery.cookie.js 操作cookie实现记住密码功能的实现代码
2011/04/27 Javascript
超精准的javascript验证身份证号的具体实现方法
2015/11/18 Javascript
基于jQuery实现Ajax验证用户名是否存在实例
2016/03/30 Javascript
Jquery给当前页或者跳转后页面的导航栏添加选中后样式的实例
2016/12/08 Javascript
js实现文字无缝向上滚动
2017/02/16 Javascript
JS中this的4种绑定规则详解
2020/02/04 Javascript
Javascript实现秒表计时游戏
2020/05/27 Javascript
vue 路由meta 设置导航隐藏与显示功能的示例代码
2020/09/04 Javascript
vue实现动态给id赋值,点击事件获取当前点击的元素的id操作
2020/11/09 Javascript
[01:02:55]CHAOS vs Mineski 2019国际邀请赛小组赛 BO2 第二场 8.16
2019/08/18 DOTA
Python selenium文件上传方法汇总
2020/11/19 Python
TensorFlow模型保存和提取的方法
2018/03/08 Python
python中redis查看剩余过期时间及用正则通配符批量删除key的方法
2018/07/30 Python
使用Python创建简单的HTTP服务器的方法步骤
2019/04/26 Python
通过实例解析python描述符原理作用
2020/01/22 Python
Python函数基本使用原理详解
2020/03/19 Python
Python通过kerberos安全认证操作kafka方式
2020/06/06 Python
10行Python代码实现Web自动化管控的示例代码
2020/08/14 Python
Tory Burch美国官方网站:美国时尚生活品牌
2016/08/01 全球购物
全球性的在线鞋类品牌:Public Desire
2019/04/03 全球购物
业务助理岗位职责
2013/11/18 职场文书
大学四年个人的自我评价
2014/02/26 职场文书
毕业生个人求职自荐信
2014/02/26 职场文书
小学生评语大全
2014/04/18 职场文书
2014小学生国庆65周年演讲稿
2014/09/21 职场文书
2014年合同管理工作总结
2014/12/02 职场文书
秋菊打官司观后感
2015/06/03 职场文书
银行服务理念口号
2015/12/25 职场文书
2019通用版新员工入职培训方案!
2019/07/11 职场文书
解决Golang中ResponseWriter的一个坑
2021/04/27 Golang
MySQL时区造成时差问题
2022/04/13 MySQL