原生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 相关文章推荐
ExtJS 2.0实用简明教程 之ExtJS版的Hello
Apr 29 Javascript
ExtJS 2.2.1的grid控件在ie6中的显示问题
May 04 Javascript
jQuery实现点击图片翻页展示效果的方法
Feb 16 Javascript
js实现九宫格图片半透明渐显特效的方法
Feb 16 Javascript
Bootstrap table的使用方法
Nov 02 Javascript
Angular实现跨域(搜索框的下拉列表)
Feb 16 Javascript
Angular.js 4.x中表单Template-Driven Forms详解
Apr 25 Javascript
微信小程序 图片宽高自适应详解
May 11 Javascript
javascript获取指定区间范围随机数的方法
Sep 08 Javascript
浅谈Vue.js 组件中的v-on绑定自定义事件理解
Nov 17 Javascript
为jquery的ajax请求添加超时timeout时间的操作方法
Sep 04 jQuery
vue+elementUI实现图片上传功能
Aug 20 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
Smarty模板引擎缓存机制详解
2016/05/23 PHP
YII2 实现多语言配置的方法分享
2017/01/11 PHP
Yii2框架类自动加载机制实例分析
2018/05/02 PHP
js禁止document element对象选中文本实现代码
2013/03/21 Javascript
angularJS 中$scope方法使用指南
2015/02/09 Javascript
JQuery中DOM加载与事件执行实例分析
2015/06/13 Javascript
javascript从定义到执行 你不知道的那些事
2016/01/04 Javascript
js添加绑定事件的方法
2016/05/15 Javascript
ion content 滚动到底部会遮住一部分视图的快速解决方法
2016/09/06 Javascript
form+iframe解决跨域上传文件的方法
2016/11/18 Javascript
JS实现仿百度文库评分功能
2017/01/12 Javascript
Vue组件开发初探
2017/02/14 Javascript
jQuery实现下拉菜单的实例代码
2017/06/19 jQuery
react-native-tab-navigator组件的基本使用示例代码
2017/09/07 Javascript
vue自定义tap指令及tap事件的实现
2018/09/18 Javascript
Node.js实现用户评论社区功能(体验前后端开发的乐趣)
2019/05/09 Javascript
react MPA 多页配置详解
2019/10/18 Javascript
JS中FormData类实现文件上传
2020/03/27 Javascript
[42:20]2014 DOTA2华西杯精英邀请赛5 24 DK VS NewBee
2014/05/25 DOTA
[47:35]VP vs Pain 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/20 DOTA
python strip()函数 介绍
2013/05/24 Python
python隐藏终端执行cmd命令的方法
2019/06/24 Python
在Python3 numpy中mean和average的区别详解
2019/08/24 Python
Python利用Scrapy框架爬取豆瓣电影示例
2020/01/17 Python
基于matplotlib xticks用法详解
2020/04/16 Python
python开发一个解析protobuf文件的简单编译器
2020/11/17 Python
Css3新特性应用之视觉效果实例
2016/12/12 HTML / CSS
Topshop美国官网:英国快速时尚品牌
2019/05/16 全球购物
Linux如何压缩可执行文件
2013/10/21 面试题
给老师的一封建议书
2014/03/13 职场文书
2014年小学教师工作自我评价
2014/09/22 职场文书
单方离婚协议书范本2014
2014/10/28 职场文书
年终工作总结范文2014
2014/11/27 职场文书
考试作弊检讨书
2015/01/27 职场文书
关爱空巢老人感想
2015/08/11 职场文书
python中pandas对多列进行分组统计的实现
2021/06/18 Python