原生JavaScript实现滚动条效果


Posted in Javascript onMarch 24, 2020

本文实例讲解原生JavaScript实现滚动条效果的相关代码,分享给大家供大家参考,具体内容如下

原理是对滑动条块进行监听,按下鼠标按键后,监听鼠标移动,然后根据滑动条块移动的百分比算出滚动区域的滚动程度,用marginLeft进行滚动,具体的写在注释里。

整体弄成了一个对象,防止各种乱七八糟的数据污染全局变量。另外,对象内部调用的函数也都写到了对象构造函数的里面,由于对象作用域链的原理,外部无法进行调用,防止不小心在外部调用。

<!DOCTYPE html>
<html>
<head>
 <title>Blank Page for Rich Text Editing</title>
 <meta http-equiv="content-type" name="author" content="Fujihara No Kokukiyo" />
 <meta charset="utf-8" />
</head>
<style rel="stylesheet" type="text/css">
 .outer{width:500px;border:1px solid black;overflow:hidden;margin:50px 0 0 100px;}
 .test_div{width:1200px;background-image:linear-gradient(90deg,lightcoral 0%,lightgreen 50%,lightblue 100%);height:150px;}
 .slider_bar,.slider_block{ border-radius:5px;}
 .slider_bar{position:relative;width:80%;margin:5px auto 5px auto;background-color:lightgreen;height:5px;}
 .slider_block{width:20px;height:5px;background-color:grey;cursor:pointer;position:absolute;}
</style>
<script type="text/javascript">
 window.onload=function(){
  /**
   * 滑动条对象构造函数,
   * 内含其他功能性函数,利用函数作用域链的原理,防止自己随意调用
   * 兼容:firefox、opera、chrome
   * ie没试,然而显然不兼容旧版本ie(8及之前),因为旧版本ie添加事件监听函数的方法不同。如若要兼容ie,还需要添加其他函数
   * js生成的滑动条类名为slider_bar、滑动块类型为slider_block,可用css样式自己设置大小、颜色等。
   * 滑动条左右padding未限制滑动条界限,如若需要限制,须在计算部分进行细小修改,加算padding,此处略去。
   *
   * @param {DOMElement} slider_content 被滚动的元素(不是被滚动元素的父元素)
   */
  function Slider(slider_content){
   //slider_instance为对象本身(在事件处理函数中会进行访问,而事件处理函数中的this对象已被注入为event.currentTarget,因此预先存储)
   var slider_instance=this;
   //this.slider_content为被滚动的元素
   this.slider_content=slider_content;
   //this.outer为被滚动元素的父元素
   this.outer=slider_content.parentNode;
   //创建滑动条
   this.slider_bar=createSliderBar();
   //创建滑动条块
   this.slider_block=createSliderBlock();
   //拼装
   this.slider_bar.appendChild(this.slider_block);
   this.outer.appendChild(this.slider_bar);
   //被滚动元素可被滚动的总宽度
   this.slider_content_width=this.slider_content.offsetWidth-this.outer.clientWidth;
   //滑动条块可滑动的总宽度
   this.slider_bar_width=this.slider_bar.clientWidth-this.slider_block.offsetWidth;
   //被滚动元素的左边距(相对父元素)
   this.slider_content_left=0;
   //滚动块的左边距(相对父元素)
   this.slider_block_left=0;
   //滑动条的左边距(相对视口)
   this.slider_bar_pageLeft=getPageLeft(this.slider_bar);
   //滑动条块添加鼠标压键事件
   this.slider_block.addEventListener("mousedown",mousedownHandler,false);
   //离开父元素后取消鼠标移动事件
   this.outer.addEventListener("mouseleave",mouseupHandler,false);
   //鼠标弹键时取消鼠标移动事件
   this.outer.addEventListener("mouseup",mouseupHandler,false);
   /**
    * 创建滑动条
    */
   function createSliderBar(){
    var slider_bar=document.createElement("div");
    slider_bar.className="slider_bar";
    return slider_bar;
   }
   /**
    * 创建滑动条块
    */
   function createSliderBlock(){
    var slider_block=document.createElement("div");
    slider_block.className="slider_block";
    return slider_block
   }
   /**
    * 鼠标按下事件处理
    */
   function mousedownHandler(event){
    //计算鼠标相对滑动块的左边距,进而在鼠标移动事件处理函数中使用
    //鼠标相对滑动块左边距=鼠标相对视口左边距-滑动块相对视口左边距
    slider_instance.mouseLeft=event.clientX-getPageLeft(this);
    console.log(getPageLeft(this));
    slider_instance.outer.addEventListener("mousemove",mousemoveHandler,false);
   }
   /**
    * 鼠标移动事件处理
    */
   function mousemoveHandler(event){
    //计算出应当设置的滑动块左边距(相对于父容器)
    //滑动块相对于滑动条左边距=鼠标相对于视口左边距-滑动条相对于视口左边距-鼠标相对于滑动块左边距
    var blockLeft=event.clientX-slider_instance.slider_bar_pageLeft-slider_instance.mouseLeft;
    //如若滑动块相对于父容器左边距大于滑动块可移动宽度或小于0,表示过界;设置为左右界限值
    if(blockLeft>slider_instance.slider_bar_width){
     blockLeft=slider_instance.slider_bar_width
    }else if(blockLeft<0){
     blockLeft=0;
    }
    //设置滑动块的新位置
    slider_instance.slider_block.style.left=blockLeft+"px";
    //按照滚动块已滚动的百分比,设置被滚动元素的marginLeft(负值),进而让其滚动起来
    //被滚动元素的左margin=-(滑动块相对于滑动条左边距/可滑动最大宽度*可滚动元素的最大宽度)
    slider_instance.slider_content.style.marginLeft="-"+(blockLeft/slider_instance.slider_bar_width*slider_instance.slider_content_width)+"px";
   }
   /**
    * 鼠标键弹起事件处理
    */
   function mouseupHandler(event){
    slider_instance.outer.removeEventListener("mousemove",mousemoveHandler,false);
   }
   /**
    * 获得元素的视口左边距
    */
   function getPageLeft(el){
    var result=el.offsetLeft;
    var parent=el.offsetParent;
    while(parent!==null){
     result+=parent.offsetLeft;
     parent=parent.offsetParent;
    }
    return result;
   }
  }
  //用test_div元素进行展示
  new Slider(document.getElementsByClassName("test_div")[0]);

 }
</script>
<body>
<div class="outer">
 <div class="test_div"></div>
</div>
</body>
</html>

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

Javascript 相关文章推荐
js 程序执行与顺序实现详解
May 13 Javascript
JS操作Cookies的小例子
Oct 15 Javascript
a标签click和href执行顺序探讨
Jun 23 Javascript
DOM基础教程之使用DOM设置文本框
Jan 20 Javascript
JS动态给对象添加事件的简单方法
Jul 19 Javascript
微信小程序购物商城系统开发系列-目录结构介绍
Nov 21 Javascript
浅谈Vue.js应用的四种AJAX请求数据模式
Aug 30 Javascript
vue router 配置路由的方法
Jul 26 Javascript
AngularJS实现的鼠标拖动画矩形框示例【可兼容IE8】
May 17 Javascript
在vue中根据光标的显示与消失实现下拉列表
Sep 29 Javascript
vue中使用elementUI组件手动上传图片功能
Dec 13 Javascript
vue路由缓存的几种实现方式小结
Feb 02 Javascript
AngularJS中如何使用$http对MongoLab数据表进行增删改查
Jan 23 #Javascript
jQuery Form 表单提交插件之formSerialize,fieldSerialize,fieldValue,resetForm,clearForm,clearFields的应用
Jan 23 #Javascript
jQuery form插件之ajaxForm()和ajaxSubmit()的可选参数项对象
Jan 23 #Javascript
jQuery form插件之formDdata参数校验表单及验证后提交
Jan 23 #Javascript
AngularJS中监视Scope变量以及外部调用Scope方法
Jan 23 #Javascript
AngularJS使用ngOption实现下拉列表的实例代码
Jan 23 #Javascript
JavaScript实现ASC转汉字及汉字转ASC的方法
Jan 23 #Javascript
You might like
PHP URL路由类实例
2013/11/12 PHP
CodeIgniter自定义控制器MY_Controller用法分析
2016/01/20 PHP
详解Laravel视图间共享数据与视图Composer
2016/08/04 PHP
php根据数据id自动生成编号的实现方法
2016/10/16 PHP
PHP上传图片时判断上传文件是否为可用图片的方法
2016/10/20 PHP
PHP设计模式之命令模式示例详解
2020/12/20 PHP
JavaScript 事件的一些重要说明
2009/10/25 Javascript
Get中文乱码IE浏览器Get中文乱码解决方案
2013/12/26 Javascript
JavaScript实现常用二级省市级联下拉列表的方法
2015/03/25 Javascript
jQuery实现带有动画效果的回到顶部和底部代码
2015/11/04 Javascript
jQuery多条件筛选如何实现
2015/11/04 Javascript
高效利用Angular中内置服务$http、$location等
2016/03/22 Javascript
详解Angular2中的编程对象Observable
2016/09/17 Javascript
使用json来定义函数,在里面可以定义多个函数的实现方法
2016/10/28 Javascript
javascript中json对象json数组json字符串互转及取值方法
2017/04/19 Javascript
vue elementui 实现搜索栏公共组件封装的实例代码
2020/01/20 Javascript
Vuex中的Mutations的具体使用方法
2020/06/01 Javascript
python实现从字符串中找出字符1的位置以及个数的方法
2014/08/25 Python
把项目从Python2.x移植到Python3.x的经验总结
2015/04/20 Python
详解Python中的Cookie模块使用
2015/07/06 Python
python获取当前目录路径和上级路径的实例
2018/04/26 Python
python按时间排序目录下的文件实现方法
2018/10/17 Python
python读取指定字节长度的文本方法
2019/08/27 Python
Python实现小黑屋游戏的完整实例
2021/01/06 Python
matplotlib更改窗口图标的方法示例
2021/02/03 Python
matplotlib交互式数据光标mpldatacursor的实现
2021/02/03 Python
计算机操作自荐信
2013/12/07 职场文书
运动会通讯稿50字
2014/01/30 职场文书
《乞巧》教学反思
2014/02/27 职场文书
医学生临床实习自我评价
2014/03/07 职场文书
商业计算机应用专业自荐书
2014/06/09 职场文书
财会专业毕业生自荐信
2014/07/09 职场文书
2014年司法局工作总结
2014/12/11 职场文书
个人先进事迹总结
2015/02/26 职场文书
毕业论文指导老师意见
2015/06/04 职场文书
企业反腐倡廉心得体会
2015/08/15 职场文书