使用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 相关文章推荐
验证控件与Button的OnClientClick事件详细解析
Dec 04 Javascript
javascript页面上使用动态时间具体实现
Mar 18 Javascript
window.open()详解及浏览器兼容性问题示例探讨
May 29 Javascript
Javascript基础教程之数据类型 (字符串 String)
Jan 18 Javascript
js实现点击图片将图片地址复制到粘贴板的方法
Feb 16 Javascript
javascript与css3动画结合使用小结
Mar 11 Javascript
jQuery的基本概念与高级编程
May 14 Javascript
JS表单验证的代码(常用)
Apr 08 Javascript
浅谈window.onbeforeunload() 事件调用ajax
Jun 29 Javascript
Angular2.js实现表单验证详解
Jun 23 Javascript
基于 Bootstrap Datetimepicker 联动
Aug 03 Javascript
vuex 中插件的编写案例解析
Jun 10 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
destoon之一键登录设置
2014/06/21 PHP
Linux下 php7安装redis的方法
2018/11/01 PHP
PHP单元测试配置与使用方法详解
2019/12/27 PHP
JS去除字符串的空格增强版(可以去除中间的空格)
2009/08/26 Javascript
js AppendChild与insertBefore用法详细对比
2013/12/16 Javascript
js/jQuery简单实现选项卡功能
2014/01/02 Javascript
JS OffsetParent属性深入解析
2014/01/13 Javascript
JS中如何判断传过来的JSON数据中是否存在某字段
2014/08/18 Javascript
Node.js开发者必须了解的4个JS要点
2016/02/21 Javascript
实例解析jQuery中proxy()函数的用法
2016/05/24 Javascript
AngularJS入门之动画
2016/07/27 Javascript
jQuery插件HighCharts绘制简单2D折线图效果示例【附demo源码】
2017/03/21 jQuery
基于Vue.js实现tab滑块效果
2017/07/23 Javascript
js中自定义react数据验证组件实例详解
2018/10/19 Javascript
jQuery实现的中英文切换功能示例
2019/01/11 jQuery
vue在自定义组件中使用v-model进行数据绑定的方法
2019/03/25 Javascript
详解vue-cli+element-ui树形表格(多级表格折腾小计)
2019/04/17 Javascript
通过实例解析jQ Ajax操作相关原理
2020/09/23 Javascript
Python判断文件和文件夹是否存在的方法
2015/05/21 Python
python实现的文件同步服务器实例
2015/06/02 Python
深入浅出分析Python装饰器用法
2017/07/28 Python
Python装饰器用法示例小结
2018/02/11 Python
详解Python循环作用域与闭包
2019/03/21 Python
tensorflow实现测试时读取任意指定的check point的网络参数
2020/01/21 Python
pygame实现飞机大战
2020/03/11 Python
只要五步 就可以用HTML5/CSS3快速制作便签贴特效(图)
2012/06/04 HTML / CSS
Lancer Skincare官方网站:抗衰老皮肤护理
2020/11/20 全球购物
雅虎笔试题(字符串操作)
2015/03/24 面试题
生物科学系大学生的自我评价
2013/12/20 职场文书
法律进学校实施方案
2014/03/15 职场文书
社区学习雷锋活动总结
2014/04/25 职场文书
离婚案件答辩状
2015/05/22 职场文书
家长对孩子的寒假评语
2015/10/09 职场文书
python 字典和列表嵌套用法详解
2021/06/29 Python
用python基于appium模块开发一个自动收取能量的小助手
2021/09/25 Python
MySQL数据库实验之 触发器和存储过程
2022/06/21 MySQL