Javascript jquery中的window.resize多次触发

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6658517/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 22:40:01  来源:igfitidea点击:

window.resize in jquery firing multiple times

javascriptjqueryjavascript-events

提问by Matt

I have the following javascript/jquery code in an HTML file:

我在 HTML 文件中有以下 javascript/jquery 代码:

<html>
  <head>
    <script src="http://code.jquery.com/jquery-1.6.2.min.js" 
     type="text/javascript"></script>
    <script language="javascript">
    $(window).resize(function(){alert('hi');});</script>
  </head>
  <body>
    resize me
  </body>
</html>

It appears relatively straight forward, however when I re size the browser window, I get two successive alert windows on Chrome and IE9 and I seemingly crash FF5.

它看起来相对简单,但是当我调整浏览器窗口的大小时,我在 Chrome 和 IE9 上得到两个连续的警报窗口,并且我似乎崩溃了 FF5。

What am I missing? Is it one fire per dimension (x/y)?

我错过了什么?每个维度 (x/y) 是一团火吗?

回答by Radu

You got it, some browsers fire on resize start and again on end while others like FF fire continuously. Solution is to use setTimeoutto avoid firing all the time. An example can be found here. Here is the code from the same reference:

你明白了,有些浏览器会在开始调整大小时再次触发,而另一些浏览器则像 FF 一样持续触发。解决方法是使用setTimeout避免一直开火。一个例子可以在这里找到。这是来自同一参考的代码:

(function($,sr){

  // debouncing function from John Hann
  // http://unscriptable.com/index.php/2009/03/20/debouncing-javascript-methods/
  var debounce = function (func, threshold, execAsap) {
      var timeout;

      return function debounced () {
          var obj = this, args = arguments;
          function delayed () {
              if (!execAsap)
                  func.apply(obj, args);
              timeout = null; 
          };

          if (timeout)
              clearTimeout(timeout);
          else if (execAsap)
              func.apply(obj, args);

          timeout = setTimeout(delayed, threshold || 100); 
      };
  }
    // smartresize 
    jQuery.fn[sr] = function(fn){  return fn ? this.bind('resize', debounce(fn)) : this.trigger(sr); };

})(jQuery,'smartresize');


// usage:
$(window).smartresize(function(){  
  // code that takes it easy...
});

回答by dave.mcalpine

here's a simple example, if the user stops resizing for 500ms (half a second) you function will fire. the clearTimeout prevents the constant refire of your function. you can adjust this value as you see fit. 500ms may be too soon, you might bump it to 1000, depends on what you are doing inside the function

这是一个简单的例子,如果用户在 500 毫秒(半秒)内停止调整大小,你的函数就会触发。clearTimeout 可防止您的功能不断重新触发。您可以根据需要调整此值。500 毫秒可能为时过早,您可能会将其提高到 1000,这取决于您在函数内部执行的操作

var resizeTimeout;
$(window).resize(function(){
    clearTimeout(resizeTimeout);
    resizeTimeout = setTimeout(function(){    
        alert('your function to run on resize');
    }, 500);
});

回答by Andrew Whitaker

Seems like this is a browser-specific quirk. According to the documentation for the resizeevent:

似乎这是一个特定于浏览器的怪癖。根据该resize事件的文档:

Code in a resize handler should never rely on the number of times the handler is called.Depending on implementation, resize events can be sent continuously as the resizing is in progress (the typical behavior in Internet Explorer and WebKit-based browsers such as Safari and Chrome), or only once at the end of the resize operation (the typical behavior in some other browsers such as Opera).

调整大小处理程序中的代码不应依赖于调用处理程序的次数。根据实现,resize 事件可以在调整大小进行时连续发送(Internet Explorer 和基于 WebKit 的浏览器(如 Safari 和 Chrome)中的典型行为),或者仅在调整大小操作结束时发送一次(在其他一些浏览器,例如 Opera)。

(emphasis mine)

(强调我的)

A workaround would be to set a timer and check to see if the dimensions of the window have changed.

一种解决方法是设置一个计时器并检查窗口的尺寸是否已更改。

回答by DSKrepps

Browsers don't fire the resize event consistently. To avoid it firing constantly, usually a setTimeout is used. Here's some more on that:

浏览器不会始终如一地触发调整大小事件。为了避免它不断触发,通常使用 setTimeout。以下是更多相关信息:

JQuery: How to call RESIZE event only once it's FINISHED resizing?

JQuery:如何仅在完成调整大小后才调用 RESIZE 事件?

JavaScript/JQuery: $(window).resize how to fire AFTER the resize is completed?

JavaScript/JQuery:$(window).resize 如何在调整大小完成后触发?