• 对 scroll 的认知和探索


    一、基础回顾:测量元素的尺寸和位置

    由于scroll中会涉及到元素的尺寸和位置的计算,这里先借助网上的一张图来回顾一下。
    图片来源自: 使用 CSSOM 测量元素尺寸和位置
    在这里插入图片描述

    clientHeight

    需要注意的是:
    clientHeight = 内容高度+上下padding-滚动条的粗度。
    对于同一个元素来说,盒模型会影响clientHeight的值。
    clientHeight返回的是整数。

    #scroll-container2 {
       
      margin: 100px 0px 70px 50px;
      border: 7px solid black;
      box-sizing: border-box; // box-sizing的值会影响clientHeight、clientWidth的值
    ​
      height: 200.22px;
      width: 300.22px;
      padding: 10px;
      overflow: auto;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    // 备注:该示例里没有水平滚动条
    getClientWidth() {
       
      /**
       * (1)对于content-box,CSS height属性只包含内容的高度,不包含padding和border。
       *      内容高度contentHeight = 200.22
       *     clientHeight = CSS height + CSS 上下padding = 200.22+10+10=220.22 clientHeight会返回整数 220
       * 
       * (2)对于border-box,CSS height属性包含了内容的高度,padding和border。
       *     内容高度contentHeight = 200.22(CSS height)-7(上border)-7(下border)-10(上padding)-10(下padding)=166.22。
       *     clientHeight = 内容height+上下padding = 166.22+10+10=186.22 clientHeight会返回整数 186
       */
      const scrollContainer = document.getElementById('scroll-container2')!;
      console.log('clientHeight', scrollContainer?.clientHeight);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    二、滚动的相关概念

    1. 当块级元素设置了 overflow: scrolloverflow: auto ,并且它包含的内容溢出了其有限的可视区时,就会显示滚动条,内容可滚动。
    2. 我们可以监听滚动事件,监听元素滚动到特定位置时做我们想做的事情。
    3. 我们也可以手动设置可滚动元素滚动指定的偏移量,比如滚动页面让指定元素进入可视区。
      在这里插入图片描述在这里插入图片描述

    一些无关紧要的示例代码:

    <div style="display: flex">
      <div id="scroll-container1">内容很少,没有滚动条div>
      <div id="scroll-container2">
        01. 内容很多,有滚动条<br />
        02. 内容很多,有滚动条<br />
        03. 内容很多,有滚动条<br />
        04. 内容很多,有滚动条<br />
        05. 内容很多,有滚动条<br />
        06. 内容很多,有滚动条<br />
        07. 内容很多,有滚动条<br />
        08. 内容很多,有滚动条<br />
        09. 内容很多,有滚动条<br />
        10. 内容很多,有滚动条<br />
        11. 内容很多,有滚动条<br />
        12. 内容很多,有滚动条<br />
        13. 内容很多,有滚动条<br />
        14. 内容很多,有滚动条<br />
        15. 内容很多,有滚动条<br />
        <div id="target">test scrollIntoView()div>
        01. 内容很多,有滚动条<br />
        02. 内容很多,有滚动条<br />
        03. 内容很多,有滚动条<br />
        04. 内容很多,有滚动条<br />
        05. 内容很多,有滚动条<br />
        06. 内容很多,有滚动条<br />
        07. 内容很多,有滚动条<br />
        08. 内容很多,有滚动条<br />
        09. 内容很多,有滚动条<br />
        10. 内容很多,有滚动条<br />
        11. 内容很多,有滚动条<br />
        12. 内容很多,有滚动条<br />
        13. 内容很多,有滚动条<br />
        14. 内容很多,有滚动条<br />
        15. 内容很多,有滚动条<br />
      div>
    div>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    #scroll-container1,
    #scroll-container2 {
       
      margin: 100px 0px 70px 50px;
      border: 7px solid black;
      box-sizing: border-box; // content-box
    
      height: 200.22px;
      width: 300.22px;
      padding: 10px;
      overflow: scroll; // auto
    }
    
    #target {
       
      height: 50px;
      padding: 10px;
      background-color: bisque;
      border: 1px solid black;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    三、监听滚动事件

    当用户滚动某个元素的内容时 scroll 事件将会被触发。
    由于 scroll 事件可被高频触发,容易造成高性能的消耗。推荐使用 requestAnimationFrame()setTimeout()CustomEvent 给事件节流,比如:

    const scrollContainer = document.getElementById('scroll-container')!;
    
    scrollContainer.addEventListener('scroll', () => {
       
      requestAnimationFrame(() => {
       
        // do something here
        console.log('我滚动啦');
      });
    });
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    显示器有固定的刷新频率,每秒最多只能重绘60次或75次,即60Hz或75Hz。requestAnimationFrame 充分利用显示器的刷新机制,与这个刷新频率保持同步,来进行页面重绘,从而节省系统资源,提高系统性能,改善视觉效果。

    四、滚动的原生API

    1. scroll()、scrollTo()、scrollBy()

    element.scroll(x-coord, y-coord) :让滚动条滚动到指定容器的某个坐标。
    element.scroll(options) :让滚动条滚动到指定容器的某个坐标,且可以指定滚动行为。
    element.scrollTo() 同 element.scroll()。

    const scrollContainer = document.getElementById('scroll-container')!;// 1. 内容垂直方向向上滚动50px
    scrollContainer.scroll(0, 50);// 2. 内容垂直方向向上滚动50px
    scrollContainer?.scroll({
       
      top: 50,
      left: 0,
      behavior: 'smooth', // 指定滚动行为,支持参数 smooth(平滑滚动),默认值auto(瞬间滚动)
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    scroll、scrollTo、scrollBy 接收参数一样。区别:
    scroll 和 scrollTo 用法基本一致。
    scrollTo 滚动的距离是 绝对 的,就是不管执行多少次,滚动的位置都是一样的。
    scrollBy 滚动的距离是 相对 的,每执行一次就会在原来的滚动基础上加上相对的距离。

    2. scrollIntoView()

    滚动element的父容器,使element对用户可见。

    element.scrollIntoView(alignToTop) :alignToTop可选。

    • 默认值为true。element的顶端将与其所在滚动区的可视区域的顶端对齐。(特殊的,如果element在其所在滚动区的可视区域的最底部,则element将与其所在滚动区的可视区域的底端对齐。)
    • 如果为false,element的底端将与其所在滚动区的可视区域的底端对齐。
  • 相关阅读:
    (Nips-2015)空间变换器网络
    数据同步、
    Karmada跨集群优雅故障迁移特性解析
    k8s 中的 ingress 使用细节
    plt保存PDF矢量文件中嵌入可编辑字体(可illustrator编辑)
    Spring Security JWT 添加额外信息
    Linux 软件包管理器 yum
    java毕业设计财务信息管理mybatis+源码+调试部署+系统+数据库+lw
    认识NAT技术
    C语言字符函数和字符串函数详解
  • 原文地址:https://blog.csdn.net/Kate_sicheng/article/details/127659037