使用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执行删除前的判断代码
Feb 18 Javascript
jQuery Easyui 验证两次密码输入是否相等
May 13 Javascript
JS实现输入框提示文字点击时消失效果
Jul 19 Javascript
浅谈JS中的bind方法与函数柯里化
Aug 10 Javascript
D3.js实现文本的换行详解
Oct 14 Javascript
详谈jQuery.load()和Jsp的include的区别
Apr 12 jQuery
AngularJS 中ui-view传参的实例详解
Aug 25 Javascript
详解如何webpack使用DllPlugin
Sep 30 Javascript
layer的prompt弹出框,点击回车,触发确定事件的方法
Sep 06 Javascript
解决Antd Table组件表头不对齐的问题
Oct 27 Javascript
使用js获取身份证年龄的示例代码
Dec 11 Javascript
Javascript之datagrid查询详解
Sep 15 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
要会喝咖啡也要会知道咖啡豆
2021/03/03 咖啡文化
PHP 处理图片的类实现代码
2009/10/23 PHP
变量在 PHP7 内部的实现(二)
2015/12/21 PHP
Symfony2安装第三方Bundles实例详解
2016/02/04 PHP
yum命令安装php7和相关扩展
2016/07/04 PHP
event.keyCode键码值表 附只能输入特定的字符串代码
2009/05/15 Javascript
javascript下4个跨浏览器必备的函数
2010/03/07 Javascript
通过jquery的$.getJSON做一个跨域ajax请求试验
2011/05/03 Javascript
jquery使用append(content)方法注意事项分享
2014/01/06 Javascript
javascript实现简单的进度条
2015/07/02 Javascript
jQuery使用ajax跨域获取数据的简单实例
2016/05/18 Javascript
javascript 定时器工作原理分析
2016/12/03 Javascript
javascript基本数据类型及类型检测常用方法小结
2016/12/14 Javascript
jQuery+C#实现参数RSA加密传输功能【附jsencrypt.js下载】
2017/06/26 jQuery
详解webpack之scss和postcss-loader的配置
2018/01/09 Javascript
详解Vue源码之数据的代理访问
2018/12/11 Javascript
vue 路由meta 设置导航隐藏与显示功能的示例代码
2020/09/04 Javascript
vue单元格多列合并的实现
2020/11/26 Vue.js
Python实现栈的方法
2015/05/26 Python
python机器学习理论与实战(一)K近邻法
2021/01/28 Python
使用python对文件中的单词进行提取的方法示例
2018/12/21 Python
celery4+django2定时任务的实现代码
2018/12/23 Python
python实现剪切功能
2019/01/23 Python
Python2和3字符编码的区别知识点整理
2019/08/08 Python
Python实现的爬取豆瓣电影信息功能案例
2019/09/15 Python
python同时替换多个字符串方法示例
2019/09/17 Python
python正则表达式实例代码
2020/03/03 Python
快速创建python 虚拟环境
2020/11/28 Python
LN-CC日本:高端男装和女装的奢侈时尚目的地
2019/09/01 全球购物
药剂专业个人求职信范文
2014/04/29 职场文书
自主招生英文自荐信
2015/03/25 职场文书
2015小学新教师个人工作总结
2015/10/14 职场文书
优质服务心得体会(共4篇)
2016/01/22 职场文书
《悬崖边的树》读后感2篇
2019/12/02 职场文书
JavaScript执行机制详细介绍
2021/12/06 Javascript
详解Mysql事务并发(脏读、不可重复读、幻读)
2022/04/29 MySQL