使用js实现一个简单的滚动条过程解析


Posted in Javascript onSeptember 10, 2019

当我们给元素加上 overflow: auto; 的时候,就会出现滚动条,然而浏览的不同,滚动条的样式大不一样,有些甚至非常丑。

于是就想着自己写一个滚动条,大概需要弄清楚一下这几个点:

1、滚动条 bar 是根据内容的多少,高度不一样的,这个需要动态的计算

2、滚动条 bar 的 top 位置 和 内容scrollTop 的关系。

思路:

使用嵌套的布局,如下:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
    <style type="text/css">
      *{
        padding: 0;
        margin: 0;
      }
      .wrap{
        width: 400px;
        height: 400px;
        border: 2px solid deeppink;
        margin: 0 auto;
        overflow: hidden;
        position: relative;
      }
      .box-middle{
        height: 100%;
        overflow: auto;
        width: 200%;
      }
      .box{
        width: 50%;
      }
      .bar{
        background: #000;
        width: 10px;
        position: absolute;
        top: 0;
        right: 0;
      }
      .s1{
        height: 400px;
        background: pink;
      }
      .s2{
        height: 400px;
        background: deeppink;
      }
      .s3{
        height: 400px;
        background: deepskyblue;
      }
    </style>
  </head>
  <body>
    <div class="wrap" id="wrap">
      <div class="box-middle" id="boxMidle">
        <div class="box" id="content">
          <div class="s1">内容1</div>
          <div class="s2">内容2</div>
          <div class="s3">内容3</div>
        </div>
      </div>
      <div class="bar" id="bar"></div>
    </div>
     
  </body>
</html>

wrap 为最外层,给overflow:hidden;。

box-middle 是中间层,也是有滚动条的一层,可以宽度给多一点,这样就看不见滚动条了。

box就是内容层,通过js,计算使得 box 的宽度和wrap 保持一致,这样就完全看不见滚动条了

bar 为滚动条

写js之前,首先要弄懂一下三个属性:

offsetHeight : height + padding + border
clientHeight : height + padding
scrollHeight : 内容的高度(所有子元素高度和) + padding

1、计算比例:

bar的高度 / wrap的高度 = wrap的高度 / wrap 内容部子元素的高度和 ; 此时忽略 wrap 的padding:0

bar的top / wrap的scrollTop = wrap的高度 / wrap 内容部子元素的高度和 ;

需要注意,当比例 的 值 小于 1 的时候,说明 这个时候没有出现滚动条。

知道算法之后,写代码就简单很多,普通版代码如下:

var $wrap = document.getElementById("wrap");
var $boxMidle = document.getElementById("boxMidle");
var $content = document.getElementById("content");
var $bar = document.getElementById("bar");
$content.style.width = $wrap.clientWidth + "px"; //内容的宽度
var rate = $boxMidle.clientHeight/ $boxMidle.scrollHeight; //滚动条高度的比例,也是滚动条top位置的比例
 var barHeight = rate * $boxMidle.clientHeight; //滚动条的 bar 的高度
if(rate < 1){
  //需要出现滚动条,并计算滚动条的高度
  $bar.style.height = barHeight + "px";
}else{
  //不需要出现滚动条
  $bar.style.display = "none";
}
$boxMidle.onscroll = function(e){
  console.log("offsetHeight"+this.offsetHeight); //height + padding + border
  console.log("clientHeight"+this.clientHeight); // height + padding
  console.log("scrollHeight"+this.scrollHeight); //内容的高度(所有子元素高度和) + padding
  console.log(this.scrollTop);
  $bar.style.top = this.scrollTop*rate + "px";
}

使用面向对象版:

function ScrollBar(opt){
  var me = this;
  me.$wrap = document.getElementById(opt.wrap);
  me.$boxMidle = document.getElementById(opt.boxMidle);
  me.$content = document.getElementById(opt.content);
  me.$bar = document.getElementById(opt.bar);
  me.init();
  me.$boxMidle.onscroll = function(e){
    //console.log("offsetHeight"+this.offsetHeight); //content + padding + border
    //console.log("clientHeight"+this.clientHeight); // content + padding
    //console.log("scrollHeight"+this.scrollHeight); //内容的高度 + padding
    console.log(this.scrollTop);
    me.scrollToY(this.scrollTop * me.rate)
  }
}
ScrollBar.prototype.init = function(){
  this.$content.style.width = this.$wrap.clientWidth + "px"; //内容的宽度
  this.rate = this.$boxMidle.clientHeight/this.$boxMidle.scrollHeight; //滚动条高度的比例,也是滚动条top位置的比例
   this.barHeight = this.rate * this.$boxMidle.clientHeight; //滚动条的 bar 的高度
  if(this.rate < 1){
    //需要出现滚动条,并计算滚动条的高度
    this.$bar.style.height = this.barHeight + "px";
  }else{
    //不需要出现滚动条
    this.$bar.style.display = "none";
  }
}
ScrollBar.prototype.scrollToY = function(y){
  if(this.rate < 1){
    this.$bar.style.top = y + 'px';
  }
}
 
var obj = new ScrollBar({"wrap":"wrap","boxMidle":"boxMidle","content":"content","bar":"bar"});

最后看一下效果:

虽然效果很丑,但是可控,自己调一下就可以了

使用js实现一个简单的滚动条过程解析

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
一个简单的javascript类定义例子
Sep 12 Javascript
Mootools 1.2教程(2) DOM选择器
Sep 14 Javascript
cnblogs TagCloud基于jquery的实现代码
Jun 11 Javascript
jQuery实现切换页面布局使用介绍
Oct 09 Javascript
禁止选中文字兼容IE、Chrome、FF等
Sep 04 Javascript
window.location的重写及判断location是否被重写
Sep 04 Javascript
浅谈javascript中this在事件中的应用
Feb 15 Javascript
JS实现鼠标滑过链接改变网页背景颜色的方法
Oct 20 Javascript
总结Javascript中数组各种去重的方法
Oct 04 Javascript
通过V8源码看一个关于JS数组排序的诡异问题
Aug 14 Javascript
js图片查看器插件用法示例
Jun 22 Javascript
基于Element封装一个表格组件tableList的使用方法
Jun 29 Javascript
html+jQuery实现拖动滑块图片拼图验证码插件【移动端适用】
Sep 10 #jQuery
Elasticsearch实现复合查询高亮结果功能
Sep 10 #Javascript
如何通过shell脚本自动生成vue文件详解
Sep 10 #Javascript
js获取 gif 的帧数的代码实例
Sep 10 #Javascript
微信小程序实现pdf、word等格式文件上传的方法
Sep 10 #Javascript
js中console在一行内打印字符串和对象的方法
Sep 10 #Javascript
layui表格内放置图片,并点击放大的实例
Sep 10 #Javascript
You might like
php获取某个目录大小的代码
2008/09/10 PHP
检测png图片是否完整的php代码
2010/09/06 PHP
php制作动态随机验证码
2015/02/12 PHP
ThinkPHP 模板substr的截取字符串函数详解
2017/01/09 PHP
PHP实现小程序批量通知推送
2018/11/27 PHP
PHP经典设计模式之依赖注入定义与用法详解
2019/05/21 PHP
Javascript String对象扩展HTML编码和解码的方法
2009/06/02 Javascript
javascript 实用的文字链提示框效果
2010/06/30 Javascript
原始XMLHttpRequest方法详情回顾
2013/11/28 Javascript
AngularJS进行性能调优的7个建议
2015/12/28 Javascript
jquery实现全选功能效果的实现代码
2016/05/05 Javascript
JavaScript6 let 新语法优势介绍
2016/07/15 Javascript
javascript设计模式之模块模式学习笔记
2017/02/15 Javascript
Nodejs 获取时间加手机标识的32位标识实现代码
2017/03/07 NodeJs
AngularJS实现的省市二级联动功能示例【可对选项实现增删】
2017/10/26 Javascript
JavaScript实现的超简单计算器功能示例
2017/12/23 Javascript
vue+element-ui动态生成多级表头的方法
2018/08/28 Javascript
详解Angular Forms中自定义ngModel绑定值的方式
2018/12/10 Javascript
koa-router路由参数和前端路由的结合详解
2019/05/19 Javascript
JavaScript静态作用域和动态作用域实例详解
2019/06/17 Javascript
vue大型项目之分模块运行/打包的实现
2020/09/21 Javascript
Python中实现从目录中过滤出指定文件类型的文件
2015/02/02 Python
PyMongo安装使用笔记
2015/04/27 Python
Python实现程序的单一实例用法分析
2015/06/03 Python
Python实现的手机号归属地相关信息查询功能示例
2017/06/08 Python
Python3使用SMTP发送带附件邮件
2020/06/16 Python
python实现得到当前登录用户信息的方法
2019/06/21 Python
Pandas库之DataFrame使用的学习笔记
2019/06/21 Python
python3 sorted 如何实现自定义排序标准
2020/03/12 Python
Python实现多线程下载脚本的示例代码
2020/04/03 Python
python 用pandas实现数据透视表功能
2020/12/21 Python
Etam俄罗斯:法国女士内衣和家居服网上商店
2019/10/30 全球购物
税务专业毕业生自荐信
2013/11/10 职场文书
农贸批发市场管理制度
2015/08/07 职场文书
Python可变与不可变数据和深拷贝与浅拷贝
2022/04/06 Python
2022微信温控新功能上线
2022/05/09 数码科技