2013-04-04 2 views
5

Я новичок в js. Пожалуйста, не мучайтесь больно. У меня есть этот кодwindow.onresize fires

window.onresize=function() {alert(1);}; 

При изменении размера любого окна browser`s, эта функция срабатывает дважды. Зачем? И как переписать этот код, код которого будет срабатывать один раз.

Thanx заранее.

+0

Думаю, нам понадобится дополнительная информация и, возможно, jsfiddle. – CaptainCarl

+2

см. Этот ответ => http://stackoverflow.com/questions/5534363/why-does-the-jquery-resize-event-fire-twice – PlantTheIdea

+3

Он не срабатывает дважды, он срабатывает каждый раз, когда браузер думает о новом изменении размера запускается. Вы должны использовать таймаут, чтобы сделать эту работу приемлемым способом. – Christoph

ответ

10

Вам нужно время ожидания для объединения событий изменения размера.

var res; 
window.onresize=function() { 
    if (res){clearTimeout(res)}; 
    res = setTimeout(function(){console.log("resize triggered");},100); 
}; 

live Example

+0

'100' слишком длинный. Пользователь может запускать два допустимых события изменения размера. Вы даже можете утверждать, что любой тайм-аут слишком длинный. Теоретически вы можете программно изменять размер окна для генерации событий с произвольными интервалами. – Halcyon

+0

@ Halcyon Я думаю, вы неправильно поняли вопрос. Цель состоит в том, чтобы подавить все последующие события изменения размера (которые, тем не менее, все еще относятся к одному и тому же изменению размера). Это сильно зависит от сценария, но при нормальном случае, когда пользователь изменяет размер своего браузера обычным способом, можно утверждать, что 100 мс, возможно, слишком низкое, но, конечно, не слишком много. – Christoph

+0

Могу сказать, что debouncing с использованием тайм-аута хотя бы немного неточно. На мой взгляд, лучший способ отладки - проверить размер окна. Если размер не изменяется, вы можете безопасно отказаться от события изменения размера. Тайм-аут хорош, но есть лучший способ. – Halcyon

6

Это событие будет срабатывать несколько раз в разных браузерах (некоторые после того, как вы закончили изменение размера, другие во время).

Один из способов обойти это - подождать определенное количество времени (скажем, полсекунды) после возникновения события, чтобы узнать, есть ли дальнейшие обновления. Если нет, вы можете продолжить предупреждение.

например.

var resizeTimer; 
window.onresize = function(){ 
    if (resizeTimer){ 
     clearTimeout(resizeTimer); 
    } 
    resizeTimer = setTimeout(function(){ 
     alert(1); 
     }, 500); 
}; 

Просмотреть результаты работы this fiddle.

+0

+1 Тот, кто ниспроверг вас, ошибается. – Christoph

+0

Мне было интересно, что это было;) – Graham

+0

Ну, так как наши ответы в точности равны, мне действительно пришлось не согласиться на это.^ – Christoph

1

Чтобы предотвратить функцию от «стрельбы» тот же результат более чем один раз, когда пользователь изменять

var doc = document; //To access the dom only once 
var cWidth = doc.body.clientWidth; 
var newWidth = cWidth; //If you want a log to show at startup, change to: newWidth = 0 
window.onresize = function(){ 
    newWidth = doc.body.clientWidth; 
    if(cWidth != newWidth){ 
     cWidth = newWidth; 
     console.log("clientWidth:", cWidth); //instead of alert(cWidth); 
    }; 
}; 
+0

Это правильный способ обнаружения события повторного изменения размера. Либо первое, либо второе событие фактически не будет изменять окно просмотра. Perpahs 'window.clientWidth/Height' лучше, чем' document.body.clientWidth'. – Halcyon

+1

@ Halcyon Вы неправильно понимаете концепцию изменения размера и/или асинхронную природу Javascript. Такой подход не решит проблему. – Christoph

0

Я предлагаю другое решение, потому что я не люблю таймауты,

`var resized; 
    window.onresize = function() { 
     if(resized){ 
      resized = false; 
     } 
     else{ 
      resized = true; 
      alert('resize'); 
     } 
    };` 
+1

Предполагается, что существует ровно два события. Если есть только одно событие или более двух событий, этот код будет неточно блокировать события. – Halcyon

Смежные вопросы