可拖拽组件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 定义function的三种方式小结
Oct 16 Javascript
jquery ajax例子返回值详解
Sep 11 Javascript
改变隐藏的input中value值的方法
Mar 19 Javascript
javascript修改IMG标签的src问题
Mar 28 Javascript
jQuery中nextUntil()方法用法实例
Jan 07 Javascript
解决BootStrap Fileinput手机图片上传显示旋转问题
Jun 01 Javascript
bootstrap paginator分页前后台用法示例
Jun 17 Javascript
关于在vue 中使用百度ueEditor编辑器的方法实例代码
Sep 14 Javascript
Vue2.0实现组件之间数据交互和通信操作示例
May 16 Javascript
6种JavaScript继承方式及优缺点(小结)
Feb 06 Javascript
JavaScript仿京东秒杀倒计时
Mar 17 Javascript
使用webpack和rollup打包组件库的方法
Feb 25 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 编写的日历
2006/10/09 PHP
php邮件发送,php发送邮件的类
2011/03/24 PHP
php网页病毒清除类
2014/12/08 PHP
PHP实现文件上传和多文件上传
2015/12/24 PHP
PHP网站常见安全漏洞,及相应防范措施总结
2021/03/01 PHP
由Javascript实现的页面日历
2011/11/04 Javascript
javascript操作select元素实例分析
2015/03/27 Javascript
javascript中replace( )方法的使用
2015/04/24 Javascript
jQuery插件jquery-barcode实现条码打印的方法
2015/11/25 Javascript
jQuery实现的指纹扫描效果实例(附演示与demo源码下载)
2016/01/26 Javascript
Laravel中常见的错误与解决方法小结
2016/08/30 Javascript
BootStrop前端框架入门教程详解
2016/12/25 Javascript
Javascript同时声明一连串(多个)变量的方法
2017/01/23 Javascript
微信小程序开发之数据存储 参数传递 数据缓存
2017/04/13 Javascript
浅谈webpack编译vue项目生成的代码探索
2017/12/11 Javascript
VUE 实现滚动监听 导航栏置顶的方法
2018/09/11 Javascript
vue与bootstrap实现简单用户信息添加删除功能
2019/02/15 Javascript
详解一次Vue低版本安卓白屏问题的解决过程
2019/05/30 Javascript
微信小程序框架的页面布局代码
2019/08/17 Javascript
Vue 嵌套路由使用总结(推荐)
2020/01/13 Javascript
JavaScript实现简单的计算器
2020/01/16 Javascript
ES5 模拟 ES6 的 Symbol 实现私有成员功能示例
2020/05/06 Javascript
[02:23]DOTA2英雄基础教程 幻影长矛手
2013/12/09 DOTA
python使用multiprocessing模块实现带回调函数的异步调用方法
2015/04/18 Python
玩转python selenium鼠标键盘操作(ActionChains)
2020/04/12 Python
Python实现读取Properties配置文件的方法
2018/03/29 Python
Python气泡提示与标签的实现
2020/04/01 Python
python文件操作seek()偏移量,读取指正到指定位置操作
2020/07/05 Python
荷兰皇家航空公司官方网站:KLM Royal Dutch Airlines
2017/12/07 全球购物
类如何去实现接口
2013/12/19 面试题
车间机修工岗位职责
2014/02/28 职场文书
2014办公室副主任四风对照检查材料思想汇报
2014/09/20 职场文书
送达通知书
2015/04/25 职场文书
舞出我人生观后感
2015/06/16 职场文书
基于Go语言构建RESTful API服务
2021/07/25 Golang
Mysql数据库手动及定时备份步骤
2021/11/07 MySQL