6

Javascript olay yoklama sıklığını nasıl azaltırsınız? Ben endişe duyduğum olaylar onResize ve onScroll. Bu olaylar, birisi tarayıcılarını yeniden boyutlandırdığında veya aşağı kaydırdığında, saniyede onlarca kez tetiklenebilir. Bu etkinliklerin yalnızca 500 ms'de bir gerçekleşmesini istiyorum. Bu yüzden, etkinlik işleyicilerimı optimize etmek ve hafızayı kaçırmadığından emin olmak için saatler harcamak zorunda kalmam. kişi boyutlandırma bittikten sonraJavascript olay yoklama sıklığını azaltın

cevap

9
var resizeTimeout; 

window.onresize = function() { 
    if (resizeTimeout) { 
     clearTimeout(resizeTimeout); 
    } 
    resizeTimeout = setTimeout(function() { 
     // Do it! 
    }, 500); 

}); 

Bu setTimeout() fonksiyon ~ 500ms tetikleyecektir.

onscroll sürümü Gerçekten olay yangınlar, sen öyle olmadığını kontrol her izleyen biri daha sonra, ilk olay ateş zaman hatırlamak gibi bir şey yapabilirsiniz ne sıklıkta kontrol edemez :)

+3

bu, her 500 ms'de bir yangın olmayacak, yalnızca – Andrey

+0

yeniden boyutlandırmayı durdur/duraklattıktan sonra 500 ms sonra ateş edecektir. İlk kez döndürüldüğünden, "resizeTimeout" için bir kontrol eklemeyi unutmayın. – casablanca

+0

@Andrey: İyi bir nokta - Bunu göz ardı ettim. – casablanca

5

çok benzer ilkinden 500 ms'den daha fazla - eğer evet, olay işleyicisiyle devam ederseniz, aksi halde sadece olaydan çıkarsınız hanlder

+0

+1, o zaman OP'nin istediği budur. Bununla birlikte, son yeniden boyutlandırma olayını işlemek için biraz ek mantığa ihtiyacınız vardır. – casablanca

+1

Zamanlayıcı çözümünün son yeniden boyutlandırma olayını ele alacağını düşünüyorum, bu nedenle gerçek çözüm iki – Andrey

1

İşleyicinizin başlangıcında, sonuncudan beri 500 msn geçip geçmediğini kontrol edin ve sadece değilse geri dönün.

1

Bu olayların tetiklenmesini engelleyemezsiniz. Her zaman yaparlar. Ne yapmak istediğinizi hemen dinlemeyi bırakın, ardından tekrarı önlemek için olayı ele alın. Daha sonra tüm işleyici setTimeout'tan sonra yeniden kurulur. Birisi pencereyi yeniden boyutlandırmazsa, daha fazla yineleme olmaz. Konsolda çalışmasını görmek daha kolay olduğu için 5000ms kullanıyorum. Bir spaz gibi yeniden boyutlandırsanız bile, her 5 saniyede bir FF konsolunda birden fazla spam görmemelisiniz. için herşeyi işleyicisi yangınları teknik olarak hala bir işleyici ve if deyimine + arama ateş her zaman yapmaya karar vermek mantığını kullanmak

(function staggerListen(){ 
    window.onresize = function(){ 
    window.onresize = false; 
    console.log('spam'); 
    setTimeout(staggerListen,5000); 
    }; 
})() 

. Bu ağırlaşabilir.

+0

Wow. Dinleyicinin geri bildirimini dinamik olarak ekleme/çıkarma, ancak her ne kadar hileli olduğu için +1'in ne olduğundan emin değilim. :) – Phrogz

0

onay çizgi

oluşturur ve sonra milisaniye o çağrılan son kez bu yana geçen beklemek yılına kadar yürütme erteleyecek geçti işlevin yeni debounced sürümünü döndürür debounce fonksiyonu. Sadece girdinin gelmeyi durdurmasından sonra gerçekleşmesi gereken davranışları uygulamak için kullanışlıdır. Örneğin: bir Markdown yorumunun önizlemesini görüntüleyerek, pencere yeniden boyutlandırmayı durdurduktan sonra düzeni yeniden hesaplar vb.

Örnek:

window.onscroll = _.debounce(
    function() { 
     // do something 
    }, 500, false 
); 
0

Kabul Yanıta gibi yapmak için kullanılan ama sorun zaman aşımı belirtilen sonra sadece tetikler vardır. Yeniden boyutlandırmayı ilk kez gerçekleştiren bir çözüm istedim. İşte işim bitti.

var _resize_is_busy = false; 
var _resize_scheduled = false; 
var _resize_precision = 100; 

// This register for window resize events. No need to change anything. 
$(window).resize(function() { 

    if (!_resize_is_busy) { 

     // call the scheduler who will do the work and set a timer to 
     // check of other resizes occured within a certain period of time 

     _resize_scheduler(); 
    } 
    else { 

     // the resizer is busy, i.e. a resize have been handled a little 
     // time ago and then the scheduler is waiting some time before 
     // handling any other resize. This flag tells the scheduler that 
     // a resize event have been receive while he was sleeping. 

     _resize_scheduled = true; 
    } 
}); 

// This is the scheduler. No need to change anything. 
var _resize_scheduler = function() { 

    _resize_is_busy = true; 
    _resize_scheduled = false; 

    setTimeout(function() { 

     _resize_is_busy = false; 

     if (_resize_scheduled) 
      _handle_resize(); 

    }, _resize_precision); 

    _handle_resize(); 
} 

var _handle_resize = function() { 

    console.log('DOING ACTUAL RESIZE'); 

    // do the work here 
    //... 
} 

Umarım bu yardımcı olur.