原生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 年会抽奖程序
Dec 22 Javascript
使用 Node.js 做 Function Test实现方法
Oct 25 Javascript
javascript实现全局匹配并替换的方法
Apr 27 Javascript
js模拟支付宝密码输入框
Apr 11 Javascript
基于angular实现三级联动的生日插件
May 12 Javascript
Vuex实现计数器以及列表展示效果
Mar 10 Javascript
vue-cli构建项目下使用微信分享功能
May 28 Javascript
vue学习笔记五:在vue项目里面使用引入公共方法详解
Apr 04 Javascript
适合前端Vue开发童鞋的跨平台Weex的使用详解
Oct 16 Javascript
Vue el-autocomplete远程搜索下拉框并实现自动填充功能(推荐)
Oct 25 Javascript
async/await让异步操作同步执行的方法详解
Nov 01 Javascript
微信小程序开发摇一摇功能
Nov 22 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
法压式咖啡之制作法
2021/03/03 冲泡冲煮
PHP模板引擎Smarty的缓存使用总结
2014/04/24 PHP
php数组中包含中文的排序方法
2014/06/03 PHP
PHP的Laravel框架结合MySQL与Redis数据库的使用部署
2016/03/21 PHP
PHP 记录访客的浏览信息方法
2018/01/29 PHP
javascript显示选择目录对话框的代码
2008/11/10 Javascript
JavaScript中的逻辑判断符&amp;&amp;、||与!介绍
2014/12/31 Javascript
jQuery中wrapAll()方法用法实例
2015/01/16 Javascript
jQuery实现form表单元素序列化为json对象的方法
2015/12/09 Javascript
jQuery获取多种input值的简单实现方法
2016/06/20 Javascript
jQuery回到顶部的代码
2016/07/09 Javascript
js HTML5多图片上传及预览实例解析(不含前端的文件分割)
2016/08/26 Javascript
基于Vue2.0+ElementUI实现表格翻页功能
2017/10/23 Javascript
Angularjs添加排序查询功能的实例代码
2017/10/24 Javascript
Node.js 使用AngularJS的方法示例
2018/05/11 Javascript
es6 filter() 数组过滤方法总结
2019/04/03 Javascript
vue表单验证你真的会了吗?vue表单验证(form)validate
2019/04/07 Javascript
js 计算月/周的第一天和最后一天代码
2020/02/01 Javascript
linux系统使用python获取cpu信息脚本分享
2014/01/15 Python
详解如何在Apache中运行Python WSGI应用
2019/01/02 Python
俄罗斯最大的消费电子连锁零售商:Mvideo
2017/06/25 全球购物
德国汽车零件和汽车配件网上商店:kfzteile24
2018/11/14 全球购物
Aquatalia官网:意大利著名鞋履品牌
2019/09/26 全球购物
Hammitt官网:设计师手袋
2020/05/23 全球购物
精细化工应届生求职信
2013/11/17 职场文书
电子商务网站的创业计划书
2014/01/05 职场文书
中药专业毕业自荐书范文
2014/02/08 职场文书
教育技术职业规划范文
2014/03/04 职场文书
2014年母亲节寄语
2014/05/07 职场文书
英语教师自荐信
2014/05/26 职场文书
百日安全生产活动总结
2014/07/05 职场文书
2019年七夕情人节浪漫祝福语大全!
2019/08/08 职场文书
优胜劣汰,强者为王——读《鲁滨逊漂流记》有感
2019/08/15 职场文书
Windows11里微软已经将驱动程序安装位置A盘删除
2021/11/21 数码科技
德劲DE1107指针试高灵敏度全波段收音机机评
2022/04/05 无线电
SQL Server数据库查询出现阻塞之性能调优
2022/04/10 SQL Server