window.resize в JQuery запускается несколько раз

У меня есть следующий код javascript/jquery в файле HTML:

<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>

Это выглядит относительно просто, однако, когда я изменяю размер окна браузера, я получаю два последовательных окна предупреждений в Chrome и IE9 и, по-видимому, вылетает FF5.

Что мне не хватает? Это один огонь на измерение (х / у)?

4 ответа

Решение

Вы получили это, некоторые браузеры запускают изменение размера начала и снова конца, в то время как другие как 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...
});

Вот простой пример: если пользователь перестанет изменять размер на 500 мс (полсекунды), ваша функция сработает. clearTimeout предотвращает постоянное обновление вашей функции. Вы можете настроить это значение по своему усмотрению. 500 мс может быть слишком рано, вы можете увеличить его до 1000, в зависимости от того, что вы делаете внутри функции

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

Похоже, это специфическая особенность браузера. Согласно документации для resize событие:

Код в обработчике изменения размера никогда не должен полагаться на количество вызовов этого обработчика. В зависимости от реализации события изменения размера могут отправляться непрерывно во время изменения размера (типичное поведение в браузерах на основе Internet Explorer и WebKit, таких как Safari и Chrome) или только один раз в конце операции изменения размера (типичное поведение в некоторые другие браузеры, такие как Opera).

(акцент мой)

Обходной путь должен был бы установить таймер и проверить, изменились ли размеры окна.

Браузеры не запускают событие изменения размера постоянно. Чтобы избежать непрерывного запуска, обычно используется setTimeout. Вот еще немного об этом:

JQuery: Как вызвать событие RESIZE только после его завершения?

JavaScript / JQuery: $ (window).resize, как запустить ПОСЛЕ изменения размера?

Другие вопросы по тегам