如何在窗口调整大小事件期间只调用一次javascript函数?

时间:2010-07-06 07:36:10

标签: jquery cross-browser webkit resize

关于jQuery resize event page,据说:

  

“调整大小处理程序中的代码永远不应该   依靠的次数   处理程序被调用。取决于   实现,调整大小事件即可   调整大小时连续发送   正在进行中(典型的行为)   Internet Explorer和基于WebKit   浏览器,如Safari和Chrome),   或者只在调整大小结束时一次   操作(典型行为)   火狐)。“

现在我发现我的应用程序中存在越来越多的内存泄漏,因为我不断调整浏览器窗口的大小,这反过来会不断触发特定的代码。我认为调整大小事件在调整大小操作结束时只调用一次,但现在看完之后我认为我的代码本身就是过度使用。

当调整大小操作已经结束时,是否有任何既定的做法只触发一次回调跨浏览器?

6 个答案:

答案 0 :(得分:6)

无论如何,当您使用jQuery时,请查看Ben Alman's doTimeout plugin。您可以使用它来debounce您的事件处理程序。

甚至有example that matches exactly your case

$(window).resize(function(){
  $.doTimeout( 'resize', 250, function(){
    // do something computationally expensive
  });
});

这里的关键是,传递给doTimeout的函数仅在未在下一个250毫秒内再次调用resize处理程序(即未触发resize事件)时执行。如果是,则中止计时器并启动新计时器。

答案 1 :(得分:3)

所以这个答案我认为最好通过执行以下操作而不是$ .doTimeout方法(它似乎不想在另一个JQuery语句中运行:

// create a global timer var:
var _timeVar;

// create your jQuery window resize method. The clearTimeout() method prevents the
$(window).resize(function(){
    clearTimeout( _timerVar );
    _timerVar = setTimeout('resizeUI()', 250);
});

// my resize function
function resizeUI() {
    // resize stuff here
}

答案 2 :(得分:1)

我认为如果你向我们展示你的resize事件处理程序会有所帮助。

如果没有看到你的代码,我可以建议有一些东西来限制每秒触发处理程序的次数:

var lastTime = 0;
$(window).resize(function(){
    // This condition will only be met (at most) once every second
    if (lastTime + 1000 < +new Date) {
        // do your stuff...
        lastTime = +new Date;
    }
});

答案 3 :(得分:0)

您可以使用旗帜。在函数开头设置标志 - 如果在完成调整大小后取消设置。然后不要再次调用该函数,除非该标志已被重置。

答案 4 :(得分:0)

感谢您的提示,但我认为它不适用于像IE或Webkit这样的浏览器,它会在调整大小时连续触发事件。 原因如下: 假设窗口没有调整大小几秒钟,然后你调整它的大小: 在第一个事件触发时,lastTime var将小于新Date,因此将执行调整大小的代码。 由于其他事件在调整大小时以高速率发射,因此它们都会在一秒钟内完成,并且不会触发。结果是调整大小不会发生在我们试图捕获的最终窗口大小上。

如果我误解了您的代码,请立即告诉我,因为我正在为此寻找解决方案,并且我希望避免在提议的其他解决方案中涉及太多的计时器。

感谢。

答案 5 :(得分:0)

Firefox启动时有多个调用(在XUL Addon中工作)。如果你想在一段时间内只调用你的代码(代码已经运行时代码再次被调用时引起的错误),你可以只使用一个触发器(flag [boolean value])。

MyClass = {
  is_resizing: false,
  // another variables here...

  resized: function() {
    if (! MyClass.is_resizing) {
      // your code goes here...
    }
  },

  // another methods here...
};

window.addEvenetListener('resize', function(e) { MyClass.resized(); e.stopPropagation(); }, false);