原生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 相关文章推荐
jQuery 表单验证扩展(四)
Oct 20 Javascript
jquery 提交值不为空的元素示例代码
May 10 Javascript
jQuery 绑定事件到动态创建的元素上的方法实例
Aug 18 Javascript
JavaScript中的this关键字使用方法总结
Mar 13 Javascript
yii form 表单提交之前JS在提交按钮的验证方法
Mar 15 Javascript
整理关于Bootstrap模态弹出框的慕课笔记
Mar 29 Javascript
老生常谈jacascript DOM节点获取
Apr 17 Javascript
jquery.tagsinput.js实现记录checkbox勾选的顺序
Sep 21 jQuery
JS实现横向轮播图(中级版)
Jan 18 Javascript
详解JavaScript中new操作符的解析和实现
Sep 04 Javascript
关于Node.js中频繁修改代码重启服务器的问题
Oct 15 Javascript
原生小程序封装跑马灯效果
Oct 21 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
Array of country list in PHP with Zend Framework
2011/10/17 PHP
PHP判断字符串长度的两种方法很实用
2015/09/22 PHP
详解WordPress中创建和添加过滤器的相关PHP函数
2015/12/29 PHP
支付宝服务窗API接口开发php版本
2016/07/20 PHP
Laravel中七个非常有用但很少人知道的Carbon方法
2017/09/21 PHP
js检测客户端不是firefox则提示下载
2007/04/07 Javascript
javascript fullscreen全屏实现代码
2009/04/09 Javascript
基于JQuery实现鼠标点击文本框显示隐藏提示文本
2012/02/23 Javascript
jQuery ajax dataType值为text json探索分享
2013/09/23 Javascript
js控制浏览器全屏示例代码
2014/02/20 Javascript
jQuery将所有被选中的checkbox某个属性值连接成字符串的方法
2015/01/24 Javascript
javasript实现密码的隐藏与显示
2015/05/08 Javascript
JavaScript编程中的Promise使用大全
2015/07/28 Javascript
JavaScript驾驭网页-CSS与DOM
2016/03/24 Javascript
js 实现省市区三级联动菜单效果
2017/02/20 Javascript
js实现一个猜数字游戏
2017/03/31 Javascript
jQuery选择器_动力节点Java学院整理
2017/07/05 jQuery
Vue如何从1.0迁移到2.0
2017/10/19 Javascript
React学习笔记之高阶组件应用
2018/06/02 Javascript
详解iview的checkbox多选框全选时校验问题
2019/06/10 Javascript
vue ssr+koa2构建服务端渲染的示例代码
2020/03/23 Javascript
[02:48]DOTA2英雄基础教程 暗夜魔王
2013/12/12 DOTA
[48:18]DOTA2-DPC中国联赛 正赛 RNG vs Dynasty BO3 第二场 1月29日
2021/03/11 DOTA
python3 破解 geetest(极验)的滑块验证码功能
2018/02/24 Python
Python实现抓取HTML网页并以PDF文件形式保存的方法
2018/05/08 Python
python实现多人聊天室
2020/03/31 Python
python接口自动化(十七)--Json 数据处理---一次爬坑记(详解)
2019/04/18 Python
讲解Python3中NumPy数组寻找特定元素下标的两种方法
2019/08/04 Python
python conda操作方法
2019/09/11 Python
利用pandas合并多个excel的方法示例
2019/10/10 Python
python读取图片颜色值并生成excel像素画的方法实例
2021/02/19 Python
html5超简单的localStorage实现记住密码的功能实现
2017/09/07 HTML / CSS
房地产出纳岗位职责
2013/12/01 职场文书
员工年终考核评语
2014/12/31 职场文书
2015年银行员工工作总结
2015/04/24 职场文书
会计专业自荐信范文
2019/05/22 职场文书