原生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解密入门之凭直觉解
Jun 25 Javascript
js 编写规范
Mar 03 Javascript
JavaScript的Module模式编程深入分析
Aug 13 Javascript
JS实现拖动示例代码
Nov 01 Javascript
jquery与prototype框架的详细对比
Nov 21 Javascript
jQuery实现响应鼠标背景变化的动态菜单效果代码
Aug 27 Javascript
简单实现js浮动框
Dec 13 Javascript
基于ajax和jsonp的原生封装(实例)
Oct 16 Javascript
Node.js readline 逐行读取、写入文件内容的示例
Mar 01 Javascript
浅谈在node.js进入文件目录的问题
May 13 Javascript
详解vuejs2.0 select 动态绑定下拉框支持多选
Apr 25 Javascript
Postman参数化实现过程及原理解析
Aug 13 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中ob_start函数的使用说明
2013/11/11 PHP
Laravel 5 框架入门(一)
2015/04/09 PHP
php+MySql实现登录系统与输出浏览者信息功能
2016/07/01 PHP
php+ajax实现带进度条的上传图片功能【附demo源码下载】
2016/09/14 PHP
PHP实现广度优先搜索算法(BFS,Broad First Search)详解
2017/09/16 PHP
php使用curl获取header检测开启GZip压缩的方法
2018/08/15 PHP
php和nginx交互实例讲解
2019/09/24 PHP
JavaScript中对象属性的添加和删除示例
2014/05/12 Javascript
javascript中日期函数new Date()的浏览器兼容性问题
2015/09/05 Javascript
基于JS2Image实现圣诞树代码
2015/12/24 Javascript
Bootstrap基本样式学习笔记之按钮(4)
2016/12/07 Javascript
AngularJS使用angular.bootstrap完成模块手动加载的方法分析
2017/01/19 Javascript
JS简单封装的图片无缝滚动效果示例【测试可用】
2017/03/22 Javascript
最全正则表达式总结:验证QQ号、手机号、Email、中文、邮编、身份证、IP地址等
2017/08/16 Javascript
Three.js如何实现雾化效果示例代码
2017/09/27 Javascript
详解在React.js中使用PureComponent的重要性和使用方式
2018/07/10 Javascript
你不知道的Vue技巧之--开发一个可以通过方法调用的组件(推荐)
2019/04/15 Javascript
深入了解响应式React Native Echarts组件
2019/05/29 Javascript
vue中通过使用$attrs实现组件之间的数据传递功能
2019/09/01 Javascript
Vue中img的src是动态渲染时不显示的解决
2019/11/14 Javascript
jquery传参及获取方式(两种方式)
2020/02/13 jQuery
[01:10:49]Secret vs VGJ.S 2018国际邀请赛淘汰赛BO3 第二场 8.24
2018/08/25 DOTA
python基础教程之实现石头剪刀布游戏示例
2014/02/11 Python
Python的Lambda函数用法详解
2019/09/03 Python
DHC中国官方购物网站:日本通信销售No.1化妆品
2016/08/20 全球购物
戴尔美国官方折扣店:Dell Outlet
2018/02/13 全球购物
DC Shoes俄罗斯官网:美国滑板鞋和服饰品牌
2020/08/19 全球购物
高级技校毕业生自荐信
2013/11/18 职场文书
文明礼仪小标兵事迹
2014/01/12 职场文书
大学生怎样写好自荐信
2014/02/25 职场文书
求职意向书范文
2014/04/01 职场文书
减负增效提质方案
2014/05/23 职场文书
护士求职信
2014/07/05 职场文书
党建工作汇报材料
2014/12/24 职场文书
2016年清明节期间群众祭祀活动工作总结
2016/04/01 职场文书
Pycharm连接远程服务器并远程调试的全过程
2021/06/24 Python