繁体   English   中英

为什么我在注册事件侦听器之前调用了滚动事件并触发了事件侦听器?

[英]Why did I call the scroll event before registering the event listener and the event listener is fired?

 window.scroll(0,10); window.addEventListener('scroll', function(e){ console.log("event;"); });

  1. 我在滚动事件之后注册了一个事件监听器,但为什么是“事件”? 显示在控制台上?
  2. 为什么会发生“事件”? 滚动发生一次时出现在控制台两次?

“滚动”事件是非常敏感的事件。 它非常敏感,以至于在其事件侦听器中使用 event.preventDefault() 并没有用,因为滚动发生在 event.preventDefault() 可以执行之前。 我使用您的代码片段创建了一个代码:

<!DOCTYPE html>
<html>

<head>
    <style>
        .large-div {
            height: 200vh;
            width: 98vw;
            background-color: #ccc;
            text-align: center;
            display: flex;
            justify-content: center;
            align-items: center;
            overflow-x: hidden;
        }
    </style>
</head>

<body>
    <div class="large-div">
        <h3>Scroll Me</h3>
    </div>
    <script>
        window.scroll(0, 10);
        window.addEventListener('scroll', function (e) {
            const lastScrollPosition = window.scrollY;
            console.log(lastScrollPosition);
        });
    </script>
</body>

</html>

我发现当我们第一次在浏览器中打开页面时,会触发一次滚动事件,但是当我刷新页面时,会触发两次滚动事件。 我从这种行为中得到的是,如果页面上有默认滚动,那么滚动事件将在页面加载时触发,这是由于滚动中的一些微小移动。

我创建了另一个动画演示来理解这一点。 在这里,我使用 animation 来增加高度。 初始高度为 10vh,这意味着页面将在没有任何滚动的情况下加载。 单击“调整大小”按钮后,animation 将启动,框颜色将变为黑色,当 animation 结束时,框颜色将变回灰色。 在这里我注意到,即使滚动开始出现在 window 上,但滚动事件直到我手动滚动 window 才会触发。

<!DOCTYPE html>
<html>

<head>
    <style>
        .large-div {
            height: 10vh;
            width: 98vw;
            background-color: #ccc;
            text-align: center;
            display: flex;
            justify-content: center;
            align-items: center;
            overflow-x: hidden;
        }

        .apply-resize-animation {
            animation-name: resize-animation;
            animation-duration: 4s;
            animation-fill-mode: forwards;
        }

        @keyframes resize-animation {
            0% {
                height: 10vh;
                background-color: #000;
            }

            25% {
                height: 70vh;
                background-color: #000;
            }

            50% {
                height: 120vh;
                background-color: #000; 
            }

            100% {
                height: 200vh;
                background-color: #ccc;
            }
        }
    </style>
</head>

<body>
    <div class="large-div">
        <button id="resize-btn">Resize Me</button>
    </div>
    <script>
        window.scroll(0, 10);
        window.addEventListener('scroll', function (e) {
            const lastScrollPosition = window.scrollY;
            console.log('Last scroll position');
            console.log(lastScrollPosition);
        });
        document.getElementById('resize-btn').addEventListener('click', function (e) {
            console.log('Resize btn clicked!');
            const toResizeElement = document.querySelector("div.large-div");
            if (!toResizeElement.classList.contains("apply-resize-animation")) {
                toResizeElement.classList.add("apply-resize-animation");
            }
        });
    </script>
</body>

</html>

您的滚动处理程序被调用两次的原因可能是因为浏览器尝试将滚动 position 恢复为刷新页面之前的状态。

为了验证这一点

  1. 删除window.scroll(0,10);
  2. 手动向下滚动页面
  3. 刷新页面
  4. 请注意,您的事件被触发。

至于为什么即使在注册处理程序之前调用window.scroll也会触发“滚动”事件,这似乎与:

这个答案可能有更多的指针https://stackoverflow.com/a/59559610/149636

猜测:

  1. 我在滚动事件之后注册了一个事件监听器,但为什么是“事件”? 显示在控制台上?
window.scroll(0,10) // Async execute and scroll called trigger onscroll event
window.addEventListener('scroll', ...) // Registered scroll sync execute
  1. 为什么会发生“事件”? 滚动发生一次时出现在控制台两次?

滚动是二维的,因为有x,y坐标点。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM