使用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中eval函数的使用方法与示例
Apr 09 Javascript
extjs_02_grid显示本地数据、显示跨域数据
Jun 23 Javascript
JavaScript学习笔记之定时器
Jan 22 Javascript
jquery图片切换插件
Mar 16 Javascript
javascript将DOM节点添加到文档的方法实例分析
Aug 04 Javascript
JS Array创建及concat()split()slice()的使用方法
Jun 03 Javascript
微信小程序 轮播图swiper详解及实例(源码下载)
Jan 11 Javascript
Javascript es7中比较实用的两个方法示例
Jul 21 Javascript
JavaScript寄生组合式继承实例详解
Jan 06 Javascript
vue.js轮播图组件使用方法详解
Jul 03 Javascript
vue动态设置img的src路径实例
Sep 18 Javascript
Vuex模块化应用实践示例
Feb 03 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/06 冲泡冲煮
php中截取中文字符串的代码小结
2011/07/17 PHP
php生成短网址示例
2014/05/05 PHP
PHP命令行脚本接收传入参数的三种方式
2014/08/20 PHP
ThinkPHP在新浪SAE平台的部署实例
2014/10/31 PHP
PHP使用DOM对XML解析处理操作示例
2019/07/04 PHP
关于this和self的使用说明
2010/08/01 Javascript
基于jquery实现的鼠标拖拽元素复制并写入效果
2011/08/23 Javascript
JS阻止冒泡事件以及默认事件发生的简单方法
2014/01/17 Javascript
使用jquery解析XML的方法
2014/09/05 Javascript
js实现分享到随页面滚动而滑动效果的方法
2015/04/10 Javascript
深入理解JS addLoadEvent函数
2016/05/20 Javascript
jQuery Easyui使用(一)之可折叠面板的布局手风琴菜单
2016/08/17 Javascript
Vue.js一个文件对应一个组件实践
2016/10/27 Javascript
Bootstrap table表格简单操作
2017/02/07 Javascript
js实现一个猜数字游戏
2017/03/31 Javascript
Redux 和 Mobx的选择问题:让你不再困惑!
2017/09/18 Javascript
jQuery实现的简单前端搜索功能示例
2017/10/28 jQuery
vue按需加载组件webpack require.ensure的方法
2017/12/13 Javascript
详解nuxt sass全局变量(公共scss解决方案)
2018/06/27 Javascript
详解React中传入组件的props改变时更新组件的几种实现方法
2018/09/13 Javascript
微信小程序实现原生步骤条
2019/07/25 Javascript
javascript实现异形滚动轮播
2019/11/28 Javascript
jQuery Datatables 动态列+跨列合并实现代码
2020/01/30 jQuery
基于原生JS封装的Modal对话框插件的示例代码
2020/09/09 Javascript
python用装饰器自动注册Tornado路由详解
2017/02/14 Python
Python 自动化表单提交实例代码
2017/06/08 Python
在pytorch中查看可训练参数的例子
2019/08/18 Python
Python多线程threading创建及使用方法解析
2020/06/17 Python
机械专业毕业生自荐信
2013/11/02 职场文书
大一期末自我鉴定
2013/12/13 职场文书
教师远程培训感言
2014/03/06 职场文书
2015新生加入学生会自荐书
2015/03/24 职场文书
酒店财务部岗位职责
2015/04/14 职场文书
行政处罚决定书
2015/06/24 职场文书
javascript的var与let,const之间的区别详解
2022/02/18 Javascript