使用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 程序库的比较(一)之DOM功能
Apr 07 Javascript
使用jQuery模板来展现json数据的代码
Oct 22 Javascript
JavaScript中使用构造器创建对象无需new的情况说明
Mar 01 Javascript
深入解析JavaScript框架Backbone.js中的事件机制
Feb 14 Javascript
基于javascript实现tab切换特效
Mar 29 Javascript
基于javascript实现最简单的选项卡切换效果
May 16 Javascript
bootstrapfileinput实现文件自动上传
Nov 08 Javascript
Bootstrap轮播图的使用和理解4
Dec 14 Javascript
微信小程序 Toast自定义实例详解
Jan 20 Javascript
angularjs实现搜索的关键字在正文中高亮出来
Jun 13 Javascript
Angular如何引入第三方库的方法详解
Jul 13 Javascript
Angular限制input框输入金额(是小数的话只保留两位小数点)
Jul 13 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的开合式多级菜单程序
2006/10/09 PHP
将数组写入txt文件 var_export
2009/04/21 PHP
php导出word文档与excel电子表格的简单示例代码
2014/03/08 PHP
解决更换PHP5.4以上版本后Dedecms后台登录空白问题的方法
2015/10/23 PHP
浅谈PHP中的
2016/04/23 PHP
javascript prototype 原型链
2009/03/12 Javascript
jqGrid随窗口大小变化自适应大小的示例代码
2013/12/28 Javascript
JavaScript生成福利彩票双色球号码
2015/05/15 Javascript
JS中生成随机数的用法及相关函数
2016/01/09 Javascript
js判断鼠标位置是否在某个div中的方法
2016/02/26 Javascript
Node.js编写爬虫的基本思路及抓取百度图片的实例分享
2016/03/12 Javascript
jQuery实现的自适应焦点图效果完整实例
2016/08/24 Javascript
Node.js数据库操作之连接MySQL数据库(一)
2017/03/04 Javascript
Vue计算属性的使用
2017/08/04 Javascript
详解如何在angular2中获取节点
2017/11/23 Javascript
node.js基础知识小结
2018/02/26 Javascript
vue双向绑定及观察者模式详解
2019/03/19 Javascript
关于angular引入ng-zorro的问题浅析
2020/09/09 Javascript
[57:22]完美世界DOTA2联赛PWL S2 FTD vs PXG 第二场 11.27
2020/12/01 DOTA
[52:02]完美世界DOTA2联赛PWL S2 FTD.C vs SZ 第一场 11.27
2020/11/30 DOTA
python按照多个字符对字符串进行分割的方法
2015/03/17 Python
Python中的探索性数据分析(功能式)
2017/12/22 Python
浅谈python中get pass用法
2019/03/19 Python
Django中在xadmin中集成DjangoUeditor过程详解
2019/07/24 Python
在tensorflow中实现屏蔽输出的log信息
2020/02/04 Python
CSS3制作3D立方体loading特效
2020/11/09 HTML / CSS
2014年语文教研组工作总结
2014/12/06 职场文书
先进典型发言材料
2014/12/30 职场文书
教师工作态度自我评价
2015/03/05 职场文书
新员工试用期工作总结2015
2015/05/28 职场文书
公务员处分决定书
2015/06/25 职场文书
呼啸山庄读书笔记
2015/06/29 职场文书
在人间读书笔记
2015/06/30 职场文书
Python可变集合和不可变集合的构造方法大全
2021/12/06 Python
使用Ajax实现无刷新上传文件
2022/04/12 Javascript
Java工作中实用的代码优化技巧分享
2022/04/21 Java/Android