使用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学习笔记(四)function函数部分
Sep 30 Javascript
超赞的jQuery图片滑块动画特效代码汇总
Jan 25 Javascript
轻松5句话解决JavaScript的作用域
Jul 15 Javascript
ionic中列表项增加和删除的实现方法
Jan 22 Javascript
详解如何用webpack打包一个网站应用项目
Jul 12 Javascript
Vue集成Iframe页面的方法示例
Dec 12 Javascript
浅谈vue项目如何打包扔向服务器
May 08 Javascript
JavaScript使用math.js进行精确计算操作示例
Jun 19 Javascript
JS实现图片转换成base64的各种应用场景实例分析
Jun 22 Javascript
layui获取多选框中的值方法
Aug 15 Javascript
jQuery实现经典的网页3D轮播图封装功能【附源码下载】
Feb 15 jQuery
如何通过setTimeout理解JS运行机制详解
Mar 23 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 Xdebug 调试扩展的安装与使用.
2010/03/13 PHP
PHP判断指定时间段的2个方法
2014/03/14 PHP
什么是PHP7中的孤儿进程与僵尸进程
2019/04/14 PHP
JS维吉尼亚密码算法实现代码
2010/11/09 Javascript
jQuery Pagination Ajax分页插件(分页切换时无刷新与延迟)中文翻译版
2013/01/11 Javascript
Javascript对象属性方法汇总
2013/11/21 Javascript
jquery遍历筛选数组的几种方法和遍历解析json对象
2013/12/13 Javascript
js采用map取到id集合组并且实现点击一行选中一行
2013/12/16 Javascript
extjs 时间范围选择自动判断的实现代码
2014/06/24 Javascript
如何实现chrome浏览器关闭页面时弹出“确定要离开此面吗?”
2015/03/05 Javascript
JavaScript递归操作实例浅析
2016/10/31 Javascript
JS中使用new Date(str)创建时间对象不兼容firefox和ie的解决方法(两种)
2016/12/14 Javascript
Vue.js实战之Vuex的入门教程
2017/04/01 Javascript
js 数字、字符串、布尔值的转换方法(必看)
2017/04/07 Javascript
JQuery元素快速查找与操作
2018/04/22 jQuery
JS实现带阴历的日历功能详解
2019/01/24 Javascript
详解JavaScript中的函数、对象
2019/04/01 Javascript
Vue2.x通用条件搜索组件的封装及应用详解
2019/05/28 Javascript
elementUI select组件value值注意事项详解
2019/05/29 Javascript
layui监听工具栏的实例(操作列表按钮)
2019/09/10 Javascript
Element-ui树形控件el-tree自定义增删改和局部刷新及懒加载操作
2020/08/31 Javascript
[02:41]2015国际邀请赛中国区预选赛观战指南
2015/05/20 DOTA
python使用paramiko模块通过ssh2协议对交换机进行配置的方法
2019/07/25 Python
HTML4和HTML5之间除了相似以外的10个主要不同
2012/12/13 HTML / CSS
HTML5 Canvas中使用用路径描画圆弧
2015/01/01 HTML / CSS
使用HTML5 Geolocation实现一个距离追踪器
2018/04/09 HTML / CSS
英国床和浴室商场:Bed & Bath Emporium
2018/05/20 全球购物
软件配置管理有什么好处
2015/04/15 面试题
工厂会计员职责
2014/02/06 职场文书
我读书我快乐演讲稿
2014/05/07 职场文书
电子商务专业毕业生求职信
2014/06/12 职场文书
采购部长岗位职责
2014/06/13 职场文书
2015年大学学生会工作总结
2015/05/13 职场文书
首都博物馆观后感
2015/06/05 职场文书
五星红旗迎风飘扬观后感
2015/06/17 职场文书
nginx静态资源的服务器配置方法
2022/07/07 Servers