使用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 相关文章推荐
js 图片等比例缩放代码
May 13 Javascript
javascript实现的使用方向键控制光标在table单元格中切换
Nov 17 Javascript
Js判断CSS文件加载完毕的具体实现
Jan 17 Javascript
js二维数组排序的简单示例代码
Jan 24 Javascript
js身份证判断方法支持15位和18位
Mar 18 Javascript
用js读、写、删除Cookie代码续篇
Dec 03 Javascript
JQuery zClip插件实现复制页面内容到剪贴板
Nov 02 Javascript
JavaScript的Backbone.js框架的一些使用建议整理
Feb 14 Javascript
三种Node.js写文件的方式
Mar 08 Javascript
浅谈Web页面向后台提交数据的方式和选择
Sep 23 Javascript
微信小程序中限制激励式视频广告位显示次数(实现思路)
Dec 06 Javascript
vue如何使用rem适配
Feb 06 Vue.js
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/03/27 PHP
php实现发送微信模板消息的方法
2015/03/07 PHP
php+jquery+html实现点击不刷新加载更多的实例代码
2016/08/12 PHP
Laravel框架集成UEditor编辑器的方法图文与实例详解
2019/04/17 PHP
根据判断浏览器类型屏幕分辨率自动调用不同CSS的代码
2007/02/22 Javascript
jQuery1.6 使用方法一
2011/11/23 Javascript
JavaScript获取和设置CheckBox状态的简单方法
2013/07/05 Javascript
JS 去前后空格大全(IE9亲测)
2013/07/15 Javascript
jquery prop的使用介绍及与attr的区别
2013/12/19 Javascript
js函数与php函数的区别实例浅析
2015/01/12 Javascript
jQuery 如何实现一个滑动按钮开关
2016/12/01 Javascript
详解angular2采用自定义指令(Directive)方式加载jquery插件
2017/02/09 Javascript
js中删除数组中的某一元素实例(无下标时)
2017/02/28 Javascript
解决linux下node.js全局模块找不到的问题
2018/05/15 Javascript
JavaScript JMap类定义与使用方法示例
2019/01/22 Javascript
vue实现动态按钮功能
2019/05/13 Javascript
JQuery中的常用事件、对象属性与使用方法分析
2019/12/23 jQuery
toString.call()通用的判断数据类型方法示例
2020/08/28 Javascript
js实现简单商品筛选功能
2021/02/02 Javascript
Webpack3+React16代码分割的实现
2021/03/03 Javascript
详解Python 解压缩文件
2019/04/09 Python
详解Numpy数组转置的三种方法T、transpose、swapaxes
2019/05/27 Python
Python发展史及网络爬虫
2019/06/19 Python
Python参数类型以及常见的坑详解
2019/07/08 Python
python判断单向链表是否包括环,若包含则计算环入口的节点实例分析
2019/10/23 Python
Django自定义列表 models字段显示方式
2020/04/03 Python
python字典的值可以修改吗
2020/06/29 Python
python 装饰器的使用示例
2020/10/10 Python
日本乐天德国站:Rakuten.de
2019/05/16 全球购物
红旗方阵解说词
2014/02/12 职场文书
材料会计岗位职责
2014/03/06 职场文书
艺术设计专业个人求职信
2014/04/10 职场文书
岗位竞聘报告范文
2014/11/06 职场文书
2014年民政工作总结
2014/11/26 职场文书
幼儿园语言教学反思
2016/02/23 职场文书
导游词之鲁迅祖居
2019/10/17 职场文书