原生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 相关文章推荐
激活 ActiveX 控件
Oct 09 Javascript
JavaScript CSS修改学习第六章 拖拽
Feb 19 Javascript
再谈javascript图片预加载技术(详细演示)
Mar 12 Javascript
javascript数字格式化通用类 accounting.js使用
Aug 24 Javascript
Flexigrid在IE下不显示数据的处理的解决方法
Oct 24 Javascript
Jquery ajax执行顺序 返回自定义错误信息(实例讲解)
Nov 06 Javascript
javaScript 计算两个日期的天数相差(示例代码)
Dec 27 Javascript
javascript正则表达式使用replace()替换手机号的方法
Jan 19 Javascript
jQuery点缩略图弹出层显示大图片
Feb 13 Javascript
js oncontextmenu事件使用详解
Mar 25 Javascript
基于jsbarcode 生成条形码并将生成的条码保存至本地+源码
Apr 27 Javascript
基于Electron实现桌面应用开发代码实例
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
PHP4实际应用经验篇(6)
2006/10/09 PHP
目录,文件操作详谈―PHP
2006/11/25 PHP
php中截取中文字符串的代码小结
2011/07/17 PHP
百度站点地图(百度sitemap)生成方法分享
2014/01/09 PHP
php实现无限级分类查询(递归、非递归)
2016/03/10 PHP
js实现的跟随鼠标移动的时钟效果(中英文日期显示)
2011/01/17 Javascript
js操作CheckBoxList实现全选/反选(在客服端完成)
2013/02/02 Javascript
JavaScript加强之自定义event事件
2013/09/21 Javascript
JavaScript splice()方法详解
2020/09/22 Javascript
js 去掉空格实例 Trim() LTrim() RTrim()
2014/01/07 Javascript
JavaScript返回网页中超链接数量的方法
2015/04/03 Javascript
基于Jquery代码实现手风琴菜单
2015/11/19 Javascript
如何使用AngularJs打造权限管理系统【简易型】
2016/05/09 Javascript
将JSON字符串转换成Map对象的方法
2016/11/30 Javascript
详解能在多种前端框架下使用的表格控件
2017/01/11 Javascript
Vue官方推荐AJAX组件axios.js使用方法详解与API
2018/10/09 Javascript
怎样使你的 JavaScript 代码简单易读(推荐)
2019/04/16 Javascript
vue数据响应式原理知识点总结
2020/02/16 Javascript
[40:56]2018DOTA2亚洲邀请赛 3.31 小组赛 A组 Liquid vs TNC
2018/04/01 DOTA
python开发之thread线程基础实例入门
2015/11/11 Python
python实现百度语音识别api
2018/04/10 Python
python怎么调用自己的函数
2020/07/01 Python
日本网路线上商品代购服务:转送JAPAN
2016/08/05 全球购物
THE OUTNET美国官网:国际设计师品牌折扣网站
2017/03/07 全球购物
皇家道尔顿官网:Royal Doulton
2017/12/06 全球购物
Supersmart英国:欧洲市场首批食品补充剂供应商之一
2018/05/05 全球购物
香港零食网购:上仓胃子
2020/06/08 全球购物
如何安装ruby on rails
2014/02/09 面试题
合作协议书怎么写
2014/04/18 职场文书
三方股东合作协议书
2014/10/28 职场文书
2014年幼儿园保育工作总结
2014/12/02 职场文书
2015年校长新年寄语
2014/12/08 职场文书
晚会闭幕词
2015/01/28 职场文书
第一节英语课开场白
2015/06/01 职场文书
python实现调用摄像头并拍照发邮箱
2021/04/27 Python
CSS实现鼠标悬浮动画特效
2023/05/07 HTML / CSS