比使用 on() 和 off() 仅在 if 子句中绑定滚动事件更好的方法?

Better way than using on() and off() to only bind scroll event in if-clause?

我只想在特定语句为真时收听 window 滚动事件,比方说 var flag。我想我会这样做,但我不确定这是否是最好的方法。

$(window).on("scroll", someFunction());
if (flag) $(window).off("scroll");

或者,可能更好,

if (flag) $(window).on("scroll", someFunction());

绑定和解除绑定滚动事件都是有成本的。在事件上调用处理程序也有成本。但更重要的是您所拥有的代码的清晰度以及您需要实现的应用程序的响应能力。

如果您能达到 60 fps,应用程序会感觉很流畅。因此,我会保持您发现的任何代码清晰并与您的代码库保持一致,并且只进行一些性能测试以查看您是否使用这些滚动处理程序获得 60 fps,并解决任何性能问题。

这个问题的答案很大程度上取决于场景。在进入解决方案之前,我们需要考虑 3 个项目,

  1. 滚动处理函数需要多久转动一次on/off
  2. 滚动事件会被多次调用。您是否需要在每次滚动时都调用您的处理函数,还是可以对其进行限制?
  3. 你的处理函数有多重?

滚动处理函数需要多久转动一次on/off?我们可以使用一个标志,

  1. bind/unbind/rebind/so...关于使用标志
  2. 在处理程序内部执行函数

您可以在测试场景后决定采用上述方法之一。这将取决于功能的开启频率 on/off。

是否需要在每次滚动时调用处理函数? Throttle 允许您每 X 秒执行一次处理函数。这比调用函数 onscroll 更好。

在这种情况下油门很好。更好的是,如果你的油门超过几秒钟,你可以结合 1a。 (bind/unbind/rebind) 每节气门秒后。同样,所有这些时间取决于您的情况。

处理函数 如果处理函数很大,那么我会寻找替代方法而不是将其绑定到滚动事件。请记住,JavaScript 执行将停止页面响应,因此即使您的脚本需要几毫秒,在每次滚动时执行它(没有节流,e.t.c)也会减慢您的页面并导致无法使用。

因为add/remove 事件处理程序的成本很高,您必须编写更多代码以防止事件处理程序被添加多次。所以我建议更简单的解决方案,一次添加事件并在处理程序开始时检查你的 flag

$(window).on("scroll", someFunction());
function someFunction() {
    if (!flag) return;
}

这样您就可以随时随地在代码中调用 flag = false; 来停止滚动事件。

如果你所说的,

I want to listen to a window scroll event only if a certain statement is true ...

确实是你想要的,那就用你的第二块代码吧。

if (flag) $(window).on("scroll", someFunction());

如果您尝试有条件地调用处理程序 onscroll,请执行以下操作 fiddle