原生js实现的移动端可拖动进度条插件功能详解


Posted in Javascript onAugust 15, 2019

本文实例讲述了原生js实现的移动端可拖动进度条插件功能。分享给大家供大家参考,具体如下:

该插件最初的想法来自网上的一篇文章,直达链接://3water.com/article/167717.htm

笔者因为业务需要寻找到这个插件,然后拿来用之,发现各种不方便,然后便开始了改造之路。

上代码:

<script>
    function dragSlide(id) {
      this.minDiv =document.getElementById(id); //小方块 
      this.width = parseInt(window.getComputedStyle(this.minDiv, null).width); //小方块的宽度
      this.lineDiv = this.minDiv.parentNode; //长线条
      //滑动的数值呈现
      this.vals = this.minDiv.children[0];
      var that=this;
      var move = function(e) {
        var x = e.touches[0].pageX;
        var lineDiv_left = that.getPosition(that.lineDiv).left; //长线条的横坐标
        var minDiv_left = x - lineDiv_left; //小方块相对于父元素(长线条)的left值
        if (minDiv_left >= that.lineDiv.offsetWidth - that.width) {
          minDiv_left = that.lineDiv.offsetWidth - that.width;
        }
        if (minDiv_left <0 ) {
          minDiv_left = 0;
        }
        //设置拖动后小方块的left值
        that.minDiv.style.left = minDiv_left + "px";
        //percent百分比改为如下所示,解决开始和最后滑动的体验不好问题
        var percent = (minDiv_left / (that.lineDiv.offsetWidth - that.width)) * 100;
        if (percent > 0 && percent < 0.5) {
          percent = Math.ceil(percent);
        } else {
          percent = Math.floor(percent);
        }
        that.vals.innerText = percent;
      }
      //获取元素的绝对位置,工具函数
      this.getPosition = function(node) {
        var left = node.offsetLeft; //获取元素相对于其父元素的left值var left
        var top = node.offsetTop;
        current = node.offsetParent; // 取得元素的offsetParent
          // 一直循环直到根元素
        
        while (current != null) {

          left += current.offsetLeft;

          top += current.offsetTop;

          current = current.offsetParent;

        }
        return {
          "left": left,
          "top": top
        };
      }
      this.minDiv.addEventListener("touchmove", move);
    }
    var drag0 = new dragSlide("minDiv");
    var drag1 = new dragSlide("minDiv1");
    //取消移动端手势长按弹出提示框的操作
    document.addEventListener('contextmenu', function(e) {
      e.preventDefault();
    });
</script>

html和css部分没有改动,而js改动还是很大的,比较原来作者的文章,改动点如下

1)整体上,原来不是插件,改造之后成为一个可以复用的插件,虽然简单了点

2)只是将其改造为适用于移动端的插件

3)通过对开始滑动和结束滑动比例的处理,优化了开始滑动和结束滑动的体验

4)移动端加了防止长按弹出提示框的代码

5)小滑块的宽度改为动态

改造之后的整体案例,需要指出:笔者主要用在微信端,至于其他浏览器滑块的体验不是很好,还有滑块滑动体验跟小块的尺寸有直接关系。

<!DOCTYPE html>
<html lang="zh-cn">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no" />
  <title>鼠标拖动小方块</title>
  <style type="text/css">
  .lineDiv {
    position: relative;
    height: 5px;
    background: red;
    width: 300px;
    margin: 50px auto;
  }
  .lineDiv .minDiv {
    position: absolute;
    top: -12.5px;
    left: 0;
    width: 30px;
    height: 30px;
    background: green;
    cursor: pointer
  }
  .lineDiv .minDiv .vals {
    position: absolute;
    font-size: 20px;
    top: -45px;
    left: -2.5px;
    width: 35px;
    height: 35px;
    line-height: 35px;
    text-align: center;
    background: blue;
  }
  .lineDiv .minDiv .vals:after {
    content: "";
    width: 0px;
    height: 0px;
    border-top: 6px solid blue;
    border-left: 6px solid transparent;
    border-right: 6px solid transparent;
    border-bottom: 6px solid transparent;
    display: block;
    margin-left: 11px;
  }
  * {
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
  }
  </style>
</head>
<body>
  <center>
    <h3>用鼠标拖动小方块<span id="msg">0</span>%</h3>
  </center>
  <div id="lineDiv" class="lineDiv">
    <div id="minDiv" class="minDiv">
      <div id="vals" class="vals">0</div>
    </div>
  </div>
  <div style="height: 20px;"></div>
  <div id="lineDiv" class="lineDiv">
    <div id="minDiv1" class="minDiv">
      <div id="vals" class="vals">0</div>
    </div>
  </div>
  <script>
  //避免默认事件 2018.7.10 更新 优化uc浏览器左右滑动时候页面被拖动
  document.addEventListener('touchmove', function(e) {
    e.preventDefault();
  }, { passive: false });
  function dragSlide(id) {
    this.minDiv = document.getElementById(id); //小方块 
    this.width = parseInt(window.getComputedStyle(this.minDiv, null).width); //小方块的宽度
    this.lineDiv = this.minDiv.parentNode; //长线条
    //滑动的数值呈现
    this.vals = this.minDiv.children[0];
    var that = this;
    var lastX = null; //判断鼠标移动方向,解决向左侧滑动时候的bug
    var move = function(e) {
      var x = e.touches[0].pageX,
        direction = '';
      if (lastX == null) {
        lastX = x;
        return;
      }
      if (x > lastX) {
        direction = 'right';
      } else if (x < lastX) {
        direction = 'left';
      } else {
        direction = '';
      }
      var lineDiv_left = that.getPosition(that.lineDiv).left; //长线条的横坐标
      var minDiv_left = x - lineDiv_left; //小方块相对于父元素(长线条)的left值
      if (minDiv_left >= that.lineDiv.offsetWidth - that.width) {
        minDiv_left = that.lineDiv.offsetWidth - that.width;
      }
      if (minDiv_left < 0) {
        minDiv_left = 0;
      }
      //设置拖动后小方块的left值
      that.minDiv.style.left = minDiv_left + "px";
      //percent百分比改为如下所示,解决开始和最后滑动的体验不好问题
      var percent = (minDiv_left / (that.lineDiv.offsetWidth - that.width)) * 100;
      if (percent < 0.5 && direction == 'right') {
        percent = Math.ceil(percent);
      } else if (percent > 0.5 && direction == 'right') {
        percent = Math.floor(percent);
      } else {
        percent = Math.ceil(percent);
      }
      that.vals.innerText = percent;
    }
    //获取元素的绝对位置,工具函数
    this.getPosition = function(node) {
      var left = node.offsetLeft; //获取元素相对于其父元素的left值var left
      var top = node.offsetTop;
      current = node.offsetParent; // 取得元素的offsetParent
        // 一直循环直到根元素
      
      while (current != null) {

        left += current.offsetLeft;

        top += current.offsetTop;

        current = current.offsetParent;

      }
      return {
        "left": left,
        "top": top
      };
    }
    this.minDiv.addEventListener("touchmove", move);
  }
  var drag0 = new dragSlide("minDiv");
  var drag1 = new dragSlide("minDiv1");
  //取消移动端手势长按弹出提示框的操作
  document.addEventListener('contextmenu', function(e) {
    e.preventDefault();
  });
  </script>
</body>
</html>

感兴趣的朋友可以使用在线HTML/CSS/JavaScript代码运行工具:http://tools.3water.com/code/HtmlJsRun测试上述代码运行效果。

更多关于JavaScript相关内容可查看本站专题:《JavaScript页面元素操作技巧总结》、《JavaScript操作DOM技巧总结》、《JavaScript切换特效与技巧总结》、《JavaScript动画特效与技巧汇总》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》及《JavaScript数学运算用法总结》

希望本文所述对大家JavaScript程序设计有所帮助。

Javascript 相关文章推荐
ASP SQL防注入的方法
Dec 25 Javascript
jQuery中filter(),not(),split()使用方法
Jul 06 Javascript
jqGrid jQuery 表格插件测试代码
Aug 23 Javascript
JavaScript基础知识之数据类型
Aug 06 Javascript
JavaScript初学者应注意的七个细节详细介绍
Dec 27 Javascript
js原型继承的两种方法对比介绍
Mar 30 Javascript
Javascript调用函数方法的几种方式介绍
Mar 20 Javascript
面向切面编程(AOP)的理解
May 01 Javascript
Node.js DES加密的简单实现
Jul 07 Javascript
jQuery插件jqGrid动态获取列和列字段的方法
Mar 03 Javascript
vue之数据交互实例代码
Jun 20 Javascript
vue实现的下拉框功能示例
Jan 29 Javascript
快速对接payjq的个人微信支付接口过程解析
Aug 15 #Javascript
Element-UI中关于table表格的那些骚操作(小结)
Aug 15 #Javascript
原生js实现可兼容PC和移动端的拖动滑块功能详解【测试可用】
Aug 15 #Javascript
js设计模式之单例模式原理与用法详解
Aug 15 #Javascript
js设计模式之代理模式及订阅发布模式实例详解
Aug 15 #Javascript
JS实现水平遍历和嵌套递归操作示例
Aug 15 #Javascript
angularjs1.X 重构controller 的方法小结
Aug 15 #Javascript
You might like
PHP_NETWORK_GETADDRESSES: GETADDRINFO FAILED问题解决办法
2014/05/04 PHP
PHP convert_cyr_string()函数讲解
2019/02/13 PHP
javascript标签在页面中的位置探讨
2013/04/11 Javascript
使用JavaScript修改浏览器URL地址栏的实现代码
2013/10/21 Javascript
xmlhttp缓存清除的2种解决方法
2013/12/13 Javascript
javascript自定义函数参数传递为字符串格式
2014/07/29 Javascript
Javascript快速排序算法详解
2014/12/03 Javascript
javascript跨域的方法汇总
2015/10/23 Javascript
使用CDN和AJAX加速WordPress中jQuery的加载
2015/12/05 Javascript
实践中学习AngularJS表单
2016/03/21 Javascript
JS实现的简易拖放效果示例
2016/12/29 Javascript
AngularJS框架的ng-app指令与自动加载实现方法分析
2017/01/04 Javascript
集合Bootstrap自定义confirm提示效果
2017/09/19 Javascript
微信小程序实现图片上传
2019/05/23 Javascript
vue-i18n实现中英文切换的方法
2020/07/06 Javascript
ant design中upload组件上传大文件,显示进度条进度的实例
2020/10/29 Javascript
[03:04]2018年国际邀请赛典藏宝瓶&莱恩声望物品展示 片尾有彩蛋
2018/06/04 DOTA
[00:06]Yes,it worked!小卡尔成功穿越时空加入战场!
2019/07/20 DOTA
Python标准库defaultdict模块使用示例
2015/04/28 Python
python中assert用法实例分析
2015/04/30 Python
Python随机生成信用卡卡号的实现方法
2015/05/14 Python
浅谈Python中的可变对象和不可变对象
2017/07/07 Python
python实现基于朴素贝叶斯的垃圾分类算法
2019/07/09 Python
TensorFLow 不同大小图片的TFrecords存取实例
2020/01/20 Python
TensorFlow 读取CSV数据的实例
2020/02/05 Python
Django多层嵌套ManyToMany字段ORM操作详解
2020/05/19 Python
html5 postMessage前端跨域并前端监听的方法示例
2018/11/01 HTML / CSS
eBay德国站:eBay.de
2017/09/14 全球购物
捷克多品牌在线时尚商店:ANSWEAR.cz
2020/10/03 全球购物
应付会计岗位职责
2013/12/12 职场文书
校庆活动策划方案
2014/06/05 职场文书
学习优秀共产党员先进事迹思想报告
2014/09/17 职场文书
2014年高中教师工作总结
2014/12/19 职场文书
义卖募捐活动总结
2015/05/09 职场文书
2015年度招聘工作总结
2015/05/28 职场文书
MySQL 可扩展设计的基本原则
2021/05/14 MySQL