原生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 相关文章推荐
(currentStyle)javascript为何有时用style得不到已设定的CSS的属性
Aug 15 Javascript
jquery 面包屑导航 具体实现
Jun 05 Javascript
jQuery使用slideUp方法实现控制元素缓慢收起
Mar 27 Javascript
easyui中combotree循环获取父节点至根节点并输出路径实现方法
Nov 10 Javascript
angular实现表单验证及提交功能
Feb 01 Javascript
微信小程序 参数传递实例代码
Mar 20 Javascript
微信小程序中setInterval的使用方法
Sep 29 Javascript
jquery select插件异步实时搜索实例代码
Oct 20 jQuery
vue组件 keep-alive 和 transition 使用详解
Oct 11 Javascript
不依任何赖第三方,单纯用vue实现Tree 树形控件的案例
Sep 21 Javascript
微信小程序APP的生命周期及页面的生命周期
Apr 19 Javascript
MutationObserver在页面水印实现起到的作用详解
Jul 07 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判断服务器是否支持Gzip压缩功能
2013/09/24 PHP
php实现二进制和文本相互转换的方法
2015/04/18 PHP
浅谈laravel-admin form中的数据,在提交后,保存前,获取并进行编辑
2019/10/21 PHP
PHP Beanstalkd消息队列的安装与使用方法实例详解
2020/02/21 PHP
jquery 将disabled的元素置为enabled的三种方法
2009/07/25 Javascript
javascript 面向对象编程基础:封装
2009/08/21 Javascript
基于jquery实现漂亮的动态信息提示效果
2011/08/02 Javascript
JS将所有对象s的属性复制给对象r(原生js+jquery)
2014/01/25 Javascript
基于jquery实现在线选座订座之影院篇
2015/08/24 Javascript
JavaScript中数组的合并以及排序实现示例
2015/10/24 Javascript
Fullpage.js固定导航栏-实现定位导航栏
2016/03/17 Javascript
jQuery中的一些常见方法小结(推荐)
2016/06/13 Javascript
JavaScript运动框架 多值运动(四)
2017/05/18 Javascript
微信小程序 密码输入(源码下载)
2017/06/27 Javascript
JavaScript之事件委托实例(附原生js和jQuery代码)
2017/07/22 jQuery
[js高手之路]HTML标签解释成DOM节点的实现方法
2017/08/31 Javascript
vue移动UI框架滑动加载数据的方法
2018/03/12 Javascript
微信小程序自定义组件之可清除的input组件
2018/07/17 Javascript
React styled-components设置组件属性的方法
2018/08/07 Javascript
解决vue语法会有延迟加载显现{{xxx}}的问题
2019/11/14 Javascript
[01:05:40]2014 DOTA2国际邀请赛中国区预选赛 5 23 CIS VS DT第三场
2014/05/24 DOTA
Python采用raw_input读取输入值的方法
2014/08/18 Python
python实现换位加密算法的示例
2018/10/14 Python
使用python打印十行杨辉三角过程详解
2019/07/10 Python
python网络编程:socketserver的基本使用方法实例分析
2020/04/09 Python
OpenCV 表盘指针自动读数的示例代码
2020/04/10 Python
python中shell执行知识点
2020/05/06 Python
python如何实现word批量转HTML
2020/09/30 Python
Python lxml库的简单介绍及基本使用讲解
2020/12/22 Python
在PyCharm中安装PaddlePaddle的方法
2021/02/05 Python
加拿大户外探险购物网站:SAIL
2020/06/27 全球购物
团日活动策划书
2014/02/01 职场文书
八月一日观后感
2015/06/10 职场文书
企业安全隐患排查治理制度
2015/08/05 职场文书
Vue和Flask通信的实现
2021/05/19 Vue.js
FP-growth算法发现频繁项集——发现频繁项集
2021/06/24 Python