拖拽属于前端常见的功能,很多效果都会用到js的拖拽功能。滑动条的核心功能也就是使用js拖拽滑块来修改位置。一个完整的滑动条包括 滑动条、滑动痕迹、滑块、文本 等元素,先把html代码写出来,如下所示:

  1. <div class="bar_wrap" id="wrap"><!--外包裹元素-->
  2. <div class="bar_container"><!--滑动条-->
  3. <div class="bar_into"></div><!--滑动痕迹-->
  4. </div>
  5. <div class="bar_drag"><!--滑块-->
  6. <div class="bar_text"></div><!--文本-->
  7. </div>
  8. </div>

然后给各元素添加css样式,完成下图效果:

接下来通过分析功能,一步一步完成js代码。

1. 获取滑动条各个元素,代码如下:

  1. //获取外包裹元素
  2. var eBarWrap = document.getElementById('wrap');
  3. //获取滑动条
  4. var eBarCon = eBarWrap.getElementsByClassName('bar_container')[0];
  5. //获取滑动痕迹元素
  6. var eBarInto = eBarWrap.getElementsByClassName('bar_into')[0];
  7. //获取滑块
  8. var eBarDrag = eBarWrap.getElementsByClassName('bar_drag')[0];
  9. //获取文本元素
  10. var eBarText = eBarWrap.getElementsByClassName('bar_text')[0];

2. 获取滑动最大值
因为滑块只能在滑动条内滑动,所以需要限制最大滑动位置。而DOM元素计算位置是从元素的左侧开始,所以最大值应该是 滑动条的宽度-滑块 的宽度,如下所示:

  1. //获取最大位置
  2. var nMax = eBarCon.offsetWidth - eBarDrag.offsetWidth;

3. 在滑块上绑定鼠标按下事件函数,实现拖拽滑块功能,代码如下:

  1. //滑块添加拖拽事件
  2. eBarDrag.addEventListener('mousedown',function(event){
  3.  
  4. });

3.1 获取滑块位置
需要拖动滑块,肯定要先知道滑块原来的位置,才能根据鼠标的移动来拖拽滑块。在滑块上绑定的事件函数上有传入一个event对象,这个event对象代表当前事件的实例对象,包含当前事件相关信息。如下所示:

  1. //滑块添加拖拽事件
  2. eBarDrag.addEventListener('mousedown',function(event){
  3. //初始化鼠标开始拖拽的点击位置
  4. var nInitX = event.clientX;
  5. //初始化滑块位置
  6. var nInitLeft = this.offsetLeft;
  7. });

3.2 滑块跟随鼠标移动,修改滑动痕迹和文本数值
操作时,在滑块上按下鼠标,再移动鼠标就可以使滑块跟随鼠标移动。但一般移动鼠标不可能只在滑动条上面移动,所以需要在页面上绑定鼠标移动事件,如下所示:

  1. //滑块添加拖拽事件
  2. eBarDrag.addEventListener('mousedown',function(event){
  3. /*...*/
  4.  
  5. //页面绑定鼠标移动事件
  6. document.onmousemove = event=>{
  7. //鼠标移动时取消默认行为,避免选中其他元素或文字
  8. event.preventDefault();
  9. //获取鼠标移动后滑块应该移动到的位置
  10. let nX = event.clientX - nInitX + nInitLeft;
  11. //限制滑块最大移动位置
  12. if(nX>=nMax){
  13. nX = nMax;
  14. }
  15. //限制滑块最小移动位置
  16. if(nX<=0){
  17. nX = 0;
  18. }
  19. //修改滑块位置(因为用的是箭头函数,所以this还是指向滑块)
  20. this.style.left = nX + 'px';
  21. //修改滑动痕迹宽度
  22. eBarInto.style.width = nX + this.offsetWidth/2 + 'px';
  23. //修改文本数值
  24. eBarText.innerHTML = Math.ceil(nX/nMax*100)/10;
  25. };
  26. });

3.3 释放鼠标时,固定滑块位置
当释放鼠标的时候,滑块固定在当前移动到的位置,滑动痕迹和文本数值已经一起修改。

  1. //滑块添加拖拽事件
  2. eBarDrag.addEventListener('mousedown',function(event){
  3. /*...*/
  4.  
  5. //鼠标松开绑定事件,取消页面上所有事件
  6. document.onmouseup = function(event){
  7. document.onmousemove = null;
  8. document.onmouseup = null;
  9. }
  10. });

鼠标按下事件函数就完成了。滑动条的样式都可以通过css实现,但默认文本数值是空的,这不太合理,所以需要加多一句代码,给文本元素默认赋值为0,如下所示:

  1. //修改默认数值
  2. eBarText.innerHTML = 0;

4. 在滑动条上添加点击事件
当点击滑动条上除滑块之外的位置时,滑块应该直接滑动到鼠标点击的位置。需要在滑动条上添加点击事件实现此功能,代码如下:

  1. //滑动条添加点击事件
  2. eBarCon.addEventListener('click',function(event){
  3. //设置滑动条位置
  4. var nLeft = this.offsetLeft;
  5. //获取有定位的父元素
  6. var eParent = this.offsetParent;
  7. //循环所有有定位的父元素
  8. while(eParent){
  9. //添加定位父元素offsetLeft值,用于准确定位滑动条与页面左侧的距离
  10. nLeft += eParent.offsetLeft;
  11. //再次获取父元素外的定位父元素
  12. eParent = eParent.offsetParent;
  13. }
  14. //计算滑块位置
  15. var nX = event.clientX - nLeft;
  16. //修改滑块位置
  17. eBarDrag.style.left = nX +'px';
  18. //修改滑动痕迹宽度
  19. eBarInto.style.width = nX + eBarDrag.offsetWidth/2 + 'px';
  20. //修改文本数值
  21. eBarText.innerHTML = Math.ceil(nX/nMax*100)/10
  22. });

原生js拖拽功能制作滑动条实例教程的更多相关文章

  1. 再谈React.js实现原生js拖拽效果

    前几天写的那个拖拽,自己留下的疑问...这次在热心博友的提示下又修正了一些小小的bug,也加了拖拽的边缘检测部分...就再聊聊拖拽吧 一.不要直接操作dom元素 react中使用了虚拟dom的概念,目 ...

  2. React.js实现原生js拖拽效果及思考

    一.起因&思路 不知不觉,已经好几天没写博客了...近来除了研究React,还做了公司官网... 一直想写一个原生js拖拽效果,又加上近来学react学得比较嗨.所以就用react来实现这个拖 ...

  3. 原生js拖拽、jQuery拖拽、vue自定义指令拖拽

    原生js拖拽: <!DOCTYPE html> <html lang="en"> <head> <meta charset="U ...

  4. 关于 JS 拖拽功能的冲突问题及解决方法

    前言 我在之前写过关于 JS 拖拽的文章,实现方式和网上能搜到的方法大致相同,别无二致,但是在一次偶然的测试中发现,这种绑定事件的方式可能会和其它的拖拽事件产生冲突,由此产生了对于事件绑定的思考.本文 ...

  5. 关于js拖拽功能,拖拽元素的position:fixed;left:0;right:0;样式引起左右拖动元素会出现落后鼠标移动距离的问题

    被拖拽元素的样式如果为:position:fixed;left:0;right:0;(当时是为了让fixed定位的元素水平居中加的left:0;right:0;避免js动态计算定位的麻烦)时左右拖动会 ...

  6. html5原生js拖拽上传(golang版)

    一次只能传一个文件,需在main.go同级目录中建一个upload文件夹 main.go package main import ( "fmt" "io" &q ...

  7. 原生js拖拽

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  8. 原生js使用面向对象的方法开发选项卡实例教程

    本教程通过js面向对象的方法来封装一个选项卡的实例,在实例中讲解js的面向对象如何实现功能. 一般封装好的选项卡程序,只需要一个div元素即可.其它元素都是通过json数据来生成,所以封装好的选项卡实 ...

  9. 通过 JS 实现简单的拖拽功能并且可以在特定元素上禁止拖拽

    前言 关于讲解 JS 的拖拽功能的文章数不胜数,我确实没有必要大费周章再写一篇重复的文章来吸引眼球.本文的重点是讲解如何在某些特定的元素上禁止拖拽.这是我在编写插件时遇到的问题,其实很多插件的拖拽功能 ...

随机推荐

  1. 实战Git命令(界面操作+命令行)

    先说明下公司的发版步骤,当需要开发一个新的功能,先从master分支中拉出一个自己的分支a(假设分支为a),在a分支开发功能完后,需要切换到dev分支,然后把自己的分支a合到dev分支,部署测试环境让 ...

  2. 查找Command

    Find [路径] [匹配表达式] -name filename : 查找指定名称的文件 -user username: 查找属于指定用户的文件 -group grpname: 查找属于指定组的文件 ...

  3. FAT32、NTFS、exFAT有什么区别?

    文件系统 我们经常会对电脑硬盘.U盘.移动硬盘进行格式化,而在格式化硬盘的时候会弹出文件系统的选项,分别有FAT32.NTFS.exFAT三种格式,那么FAT32.NTFS.exFAT有什么区别? 在 ...

  4. 聊聊 g0

    很多时候,当我们跟着源码去理解某种事物时,基本上可以认为是以时间顺序展开,这是编年体的逻辑.还有另一种逻辑,纪传体,它以人物为中心编排史事,使得读者更聚焦于某个人物.以一种新的视角,把所有的事情串连起 ...

  5. 【Oracle】修改列的大小

    alter table 表名 modify column_name varchar2(32)  alter table 表名 modify (column_name1 varchar(20) defa ...

  6. 知识图谱KnowledgeGraph核心技术培训班 2月03日— 2月06日

  7. Django-http协议

    Http协议:超文本传输协议(应用层程序).它是客户端和服务端请求和应答的标准.Http的请求响应模型:1.客户端连接到web服务器一个http客户端,与web服务器的http端口(默认是80)建立了 ...

  8. Vue基础之Vue的模板语法

    Vue基础之Vue的模板语法 数据绑定 01 数据绑定最常见的形式就是使用插值表达式(两个大括号!)[也就是小胡子语法!mustache] <body> <!-- Vue.js的应用 ...

  9. 借助 AppleScript 一键打开工作空间

    我有个小毛病:同时只能在一个工程里工作. 假如让我开四五个 Webstorm,在工程里 A 改个Bug,然后又到工程 B 里加个需求,再去工程 C 发个版,切来切去一会儿就懵了. 于是有了这个项目:m ...

  10. oblet

      oblet - The Go Programming Language https://golang.google.cn/search?q=oblet // put enqueues a poin ...