JavaScript 滚动事件

摘要:在本教程中,您将学习关于 JavaScript 滚动事件以及如何正确处理滚动事件。

JavaScript 滚动事件简介

当您滚动文档或元素时,浏览器会触发滚动事件。您可以通过以下方式触发滚动事件:

  • 使用滚动条手动滚动
  • 使用鼠标滚轮
  • 单击 ID 链接
  • 在 JavaScript 中调用函数
  • 等等。

要注册 scroll 事件处理程序,请在目标元素上调用 addEventListener() 方法,如下所示:

targetElement.addEventListener('scroll', (event) => {
    // handle the scroll event 
});Code language: PHP (php)

或将事件处理程序分配给目标元素的 onscroll 属性:

targetElement.onscroll = (event) => {
    // handle the scroll event
};Code language: JavaScript (javascript)

滚动文档

通常,您会在 window 对象上注册 scroll 事件的事件处理程序,以处理整个页面的滚动。

例如,以下示例演示了如何将事件处理程序附加到页面的 scroll 事件:

window.addEventListener('scroll',(event) => {
    console.log('Scrolling...');
});Code language: JavaScript (javascript)

或者,您可以使用 window 对象上的 onscroll 属性:

window.onscroll = function(event) {
    //
};Code language: JavaScript (javascript)

window 对象的 onscroll 属性与 document.body.onscroll 相同,您可以互换使用它们,例如:

document.body.onscroll = null;
console.log(window.onscroll); // nullCode language: JavaScript (javascript)

滚动偏移量

window 对象有两个与滚动事件相关的属性:scrollXscrollY

scrollXscrollY 属性返回文档当前水平和垂直滚动的像素数。scrollXscrollY 是双精度浮点数,因此如果您需要整数,可以使用 Math.round() 对它们进行四舍五入。

如果文档根本没有滚动,则 scrollXscrollY 为 0。

pageXOffsetpageYOffsetscrollXscrollY 属性的别名。

滚动元素

window 对象类似,您可以将 scroll 事件处理程序附加到任何 HTML 元素。但是,要跟踪滚动偏移量,您使用 scrollTopscrollLeft 而不是 scrollXscrollY

scrollTop 属性设置或获取元素内容垂直滚动的像素数。scrollLeft 属性获取和设置元素内容从其左边缘滚动的像素数。

以下示例演示了如何处理 ID 为 scrollDemodiv 元素的 scroll 事件:

<!DOCTYPE html>
<html>
<head>
    <title>JS Scroll Events</title>
    <style>
        #scrollDemo {
            height: 200px;
            width: 200px;
            overflow: auto;
            background-color: #f0db4f
        }

        #scrollDemo p {
            /* show the scrollbar */
            height: 300px;
            width: 300px;
        }
    </style>
</head>
<body>
    <div id="scrollDemo">
        <p>JS Scroll Event Demo</p>
    </div>

    <div id="control">
        <button id="btnScrollLeft">Scroll Left</button>
        <button id="btnScrollTop">Scroll Top</button>
    </div>

    <script>
        let control = document.querySelector('#control');

        control.addEventListener('click', function (e) {
            // get the scrollDemo
            let div = document.getElementById('scrollDemo');
            // get the target
            let target = e.target;
            // handle each button's click
            switch (target.id) {
                case 'btnScrollLeft':
                    div.scrollLeft += 20;
                    break;

                case 'btnScrollTop':
                    div.scrollTop += 20;
                    break;
            }
        });
    </script>
</body>
</html>
Code language: HTML, XML (xml)

处理滚动事件的更好方法

当您滚动页面或元素时,会触发许多 scroll 事件。如果您将事件侦听器附加到 scroll 事件,则事件处理程序中的代码需要时间执行。

这会导致一个问题,称为滚动卡顿。滚动卡顿效应会导致延迟,因此页面感觉不到与您的手指绑定在一起。

事件节流

最好使用计时器使 scroll 事件处理程序轻量级并每 N 毫秒执行一次。因此,您不应该使用以下代码(而且您永远不应该使用它):

window.scroll = () => {
    // place the scroll handling logic here
};
Code language: JavaScript (javascript)

您应该使用以下代码:

let scrolling = false;

window.scroll = () => {
    scrolling = true;
};

setInterval(() => {
    if (scrolling) {
        scrolling = false;
        // place the scroll handling logic here
    }
},300);
Code language: JavaScript (javascript)

工作原理

  • 首先,将 scrolling 标志设置为 false。如果 scroll 事件触发,则在 scroll 事件处理程序中将 scrolling 标志设置为 true
  • 然后,如果 scroll 事件已触发,则使用 setInterval() 每 300 毫秒执行一次 scroll 事件处理程序。

这种处理 scroll 事件的方法称为事件节流,它每 300 毫秒节流一次 onscroll 的基础操作。节流会降低滚动事件处理程序的执行速度。

被动事件

最近,现代 Web 浏览器已开始支持用于输入事件(如 scrolltouchstartwheel 等)的被动事件。它允许 UI 线程在将控制权传递给您的自定义事件处理程序之前立即处理事件。

在支持被动事件的 Web 浏览器中,您需要将 passive 标志添加到任何不调用 preventDefault() 的事件侦听器,如下所示:

document.addEventListener(
    'scroll',
    (event) => {
        // handle scroll event
    }, 
    { passive: true }
);
Code language: JavaScript (javascript)

如果没有 passive 选项,事件处理程序中的代码将在 UI 线程执行滚动之前始终被调用。

查看哪些浏览器支持被动事件 此处

摘要

  • 当您滚动网页或元素时,scroll 事件会触发。
  • 对于页面,scrollXscrollY 属性返回文档当前水平和垂直滚动的像素数。
  • 对于元素,scrollTopscrollLeft 属性设置或获取元素内容垂直滚动的像素数以及从其左边缘滚动的像素数。
  • 使用事件节流技术来更好地处理滚动事件。在现代 Web 浏览器中,您可以使用被动事件侦听器。
本教程是否有帮助?