使用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 DataSet数据源处理代码
Mar 29 Javascript
js浮点数精确计算(加、减、乘、除)
Dec 26 Javascript
使用jQuery实现input数值增量和减量的方法
Jan 24 Javascript
jQuery超简单选项卡完整实例
Sep 26 Javascript
jQuery鼠标悬浮链接弹出跟随图片实例代码
Jan 08 Javascript
js实现表单提交后不重新刷新当前页面
Nov 30 Javascript
常用jQuery选择器汇总
Feb 02 Javascript
JavaScript与JQUERY获取元素的宽、高和位置
Feb 26 Javascript
bootstrap插件treeview实现全选父节点下所有子节点和反选功能
Jul 21 Javascript
vue+webpack实现异步组件加载的方法
Feb 03 Javascript
Vue 页面跳转不用router-link的实现代码
Apr 12 Javascript
QT与javascript交互数据的实现
May 26 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中empty is_null和isset的测试
2013/06/29 PHP
Symfony核心类概述
2016/03/17 PHP
php静态成员方法和静态的成员属性的使用方法
2017/10/26 PHP
JavaScript实现Sleep函数的代码
2007/03/04 Javascript
jQuery使用手册之 事件处理
2007/03/24 Javascript
js 省地市级联选择
2010/02/07 Javascript
JS定义回车事件(实现代码)
2013/07/08 Javascript
Android中的jQuery:AQuery简介
2014/05/06 Javascript
javascript查询字符串参数的方法
2015/01/28 Javascript
Bootstrap实现响应式导航栏效果
2015/12/28 Javascript
基于jquery实现三级下拉菜单
2016/05/10 Javascript
json对象与数组以及转换成js对象的简单实现方法
2016/06/24 Javascript
AngularJS入门教程之MVC架构实例分析
2016/11/01 Javascript
angular 基于ng-messages的表单验证实例
2017/05/04 Javascript
JS实现将二维数组转为json格式字符串操作示例
2018/07/12 Javascript
解决layer图标icon不加载的问题
2019/09/04 Javascript
谈谈我在vue-cli3中用预渲染遇到的坑
2020/04/22 Javascript
Element Input输入框的使用方法
2020/07/26 Javascript
python函数缺省值与引用学习笔记分享
2013/02/10 Python
让python同时兼容python2和python3的8个技巧分享
2014/07/11 Python
跟老齐学Python之使用Python查询更新数据库
2014/11/25 Python
Python中动态检测编码chardet的使用教程
2017/07/06 Python
Python最火、R极具潜力 2017机器学习调查报告
2017/12/11 Python
keras实现调用自己训练的模型,并去掉全连接层
2020/06/09 Python
keras用auc做metrics以及早停实例
2020/07/02 Python
美国电子产品购物网站:BuyDig.com
2020/06/17 全球购物
C#软件工程师英语面试题
2015/06/07 面试题
JVM是一个编译程序还是解释程序
2012/09/11 面试题
教育局长自荐信范文
2013/12/22 职场文书
2014年党建工作汇报材料
2014/10/27 职场文书
2014年银行柜员工作总结
2014/11/12 职场文书
2015医院个人工作总结范文
2015/05/21 职场文书
惊涛骇浪观后感
2015/06/05 职场文书
2015年学校教研室主任工作总结
2015/07/20 职场文书
初中思想品德教学反思
2016/02/24 职场文书
Mysql 数据库中的 redo log 和 binlog 写入策略
2022/04/26 MySQL