返回

如何解决滚动事件触发失败问题:无论先前的输入如何,都能始终触发滚动行为

javascript

如何解决滚动事件触发失败的问题

引言

当构建交互式网页时,确保事件处理程序能够正常触发至关重要。但是,有时滚动事件可能会遇到问题,即使在似乎应该触发的情况下也不触发。本文将探讨导致此问题的原因,并提供一种解决方案,以确保无论先前的输入如何,都能始终触发滚动事件。

问题

在构建一个允许用户使用鼠标滚轮或单击和拖动来查看图像的网页动画时,我们遇到了一个问题。我们期望无论用户首先选择哪种输入,滚动事件都应按预期工作。然而,在初始单击和拖动之前,滚动输入不起作用。

原因分析

我们检查了代码,发现问题出在事件处理程序中的逻辑。事件处理程序包含一个条件语句,用于检查 track.dataset.mouseDownAt 的值,该值存储了鼠标按下时的 clientY。如果该值为 "0",则表示鼠标未按下,事件处理程序将返回,不会触发滚动行为。

解决方案

为了修复此问题,我们修改了事件处理程序中的逻辑,以便无论先前的输入如何,都能触发滚动行为。我们反转了条件语句,如下所示:

if (track.dataset.mouseDownAt !== "0") return;

此更改确保仅在鼠标按下时才会触发事件处理程序。因此,无论用户是否先单击和拖动,滚动行为都将始终触发。

更新后的代码

以下是修改后的事件处理程序代码:

window.addEventListener("wheel", e => {

    e.preventDefault();
    
    const deltaY = e.deltaY;
    const maxDelta = window.innerHeight;
    
    let percentage = (deltaY / maxDelta) * -100,
        nextPercentage = parseFloat(track.dataset.percentage) + percentage;
    
    nextPercentage = Math.max(-100, Math.min(0, nextPercentage));
    
    track.dataset.percentage = nextPercentage;
    
    track.animate(
        { transform: `translate(-50%, ${nextPercentage}%)` },
        { duration: 1200, fill: "forwards" }
    );
    
    for (const image of track.getElementsByClassName("image")) {
        image.animate(
            { objectPosition: `50% ${nextPercentage + 100}%` },
            { duration: 1200, fill: "forwards" }
        );
    }
    scrollStartY = e.pageY;

    if (track.dataset.mouseDownAt !== "0") return; // 仅在鼠标按下时返回
});

结论

通过实现此更改,我们确保滚动事件始终触发,从而允许用户使用鼠标滚轮或单击和拖动来查看图像,无论先前的输入是什么。通过仔细分析问题并调整事件处理程序中的逻辑,我们能够成功地解决了这个问题,从而使网页动画更具交互性和用户友好性。

常见问题解答

  1. 为什么在最初单击和拖动之前滚动输入不起作用?

    • 因为事件处理程序中的条件语句阻止了它在鼠标按下之前触发。
  2. 如何修复此问题?

    • 通过修改条件语句,使事件处理程序仅在鼠标按下时触发。
  3. 为什么修改条件语句是必要的?

    • 为了确保无论先前的输入如何,都能触发滚动行为。
  4. 更改事件处理程序后需要修改其他代码吗?

    • 不,事件处理程序之外的代码不需要修改。
  5. 此解决方案是否适用于其他类型的滚动事件?

    • 是的,此解决方案可以应用于需要在任何情况下都能触发的任何类型的滚动事件。