JavaScript / JQuery: $ (window) .resize como triggersr APÓS o redimensionamento estar completo?

Estou usando o JQuery como tal:

$(window).resize(function() { ... }); 

No entanto, parece que se a pessoa resize manualmente as janelas do navegador arrastando a borda da janela para torná-la maior / menor, o evento .resize acima será triggersdo várias vezes.

Pergunta: Como chamar uma function APÓS o redimensionamento da janela do navegador concluído (para que o evento seja triggersdo apenas uma vez)?

Aqui está uma modificação da solução do CMS que pode ser chamada em vários lugares em seu código:

 var waitForFinalEvent = (function () { var timers = {}; return function (callback, ms, uniqueId) { if (!uniqueId) { uniqueId = "Don't call this twice without a uniqueId"; } if (timers[uniqueId]) { clearTimeout (timers[uniqueId]); } timers[uniqueId] = setTimeout(callback, ms); }; })(); 

Uso:

 $(window).resize(function () { waitForFinalEvent(function(){ alert('Resize...'); //... }, 500, "some unique string"); }); 

A solução do CMS é boa se você a chamar apenas uma vez, mas se você a chamar várias vezes, por exemplo, se partes diferentes do seu código configurarem callbacks separados para o redimensionamento da janela, então falhará b / c eles compartilham a variável timer .

Com essa modificação, você fornece um ID exclusivo para cada retorno de chamada e esses IDs exclusivos são usados ​​para manter todos os events de tempo limite separados.

Eu prefiro criar um evento:

 $(window).bind('resizeEnd', function() { //do something, window hasn't changed size in 500ms }); 

Aqui está como você cria:

  $(window).resize(function() { if(this.resizeTO) clearTimeout(this.resizeTO); this.resizeTO = setTimeout(function() { $(this).trigger('resizeEnd'); }, 500); }); 

Você poderia ter isso em um arquivo javascript global em algum lugar.

Eu uso a seguinte function para atrasar ações repetidas, ela funcionará para o seu caso:

 var delay = (function(){ var timer = 0; return function(callback, ms){ clearTimeout (timer); timer = setTimeout(callback, ms); }; })(); 

Uso:

 $(window).resize(function() { delay(function(){ alert('Resize...'); //... }, 500); }); 

A function de retorno de chamada passada a ele será executada somente quando a última chamada para atraso tiver sido feita após o período de tempo especificado; caso contrário, um cronômetro será redefinido. Isso é útil para outros fins, como detectar quando o usuário parou de digitar etc. ..

Se você tiver Underscore.js instalado, você poderia:

 $(window).resize(_.debounce(function(){ alert("Resized"); },500)); 

Algumas das soluções mencionadas anteriormente não funcionaram para mim, embora sejam de uso mais geral. Como alternativa, encontrei este que fez o trabalho no redimensionamento da janela:

 $(window).bind('resize', function(e){ window.resizeEvt; $(window).resize(function(){ clearTimeout(window.resizeEvt); window.resizeEvt = setTimeout(function(){ //code to do after window is resized }, 250); }); }); 

Muito obrigado a David Walsh, aqui está uma versão baunilha do debounce de sublinhado.

Código:

 // Returns a function, that, as long as it continues to be invoked, will not // be triggered. The function will be called after it stops being called for // N milliseconds. If `immediate` is passed, trigger the function on the // leading edge, instead of the trailing. function debounce(func, wait, immediate) { var timeout; return function() { var context = this, args = arguments; var later = function() { timeout = null; if (!immediate) func.apply(context, args); }; var callNow = immediate && !timeout; clearTimeout(timeout); timeout = setTimeout(later, wait); if (callNow) func.apply(context, args); }; }; 

Uso simples:

 var myEfficientFn = debounce(function() { // All the taxing stuff you do }, 250); $(window).on('resize', myEfficientFn); 

Ref: http://davidwalsh.name/javascript-debounce-function

Veja esta resposta: javascript resize evento triggersndo várias vezes enquanto arrasta a alça de redimensionamento

Envolve o uso de tempos limite para atrasar a execução de sua function.

Na verdade, como eu sei, você não pode fazer algumas ações exatamente quando o redimensionamento está desativado, simplesmente porque você não sabe as ações do usuário futuro. Mas você pode assumir o tempo passado entre dois events de redimensionamento, então se você esperar um pouco mais que esse tempo e nenhum redimensionamento for feito, você pode chamar sua function.
A ideia é que usamos o setTimeout e o id para salvá-lo ou excluí-lo. Por exemplo, sabemos que o tempo entre dois events de redimensionamento é de 500 ms, portanto, esperaremos 750 ms.

 var a; $(window).resize(function(){ clearTimeout(a); a = setTimeout(function(){ // call your function },750); }); 

Plugin jQuery simples para evento de redimensionamento de janela atrasada.

SINTAXE:

Adicionar nova function para resize evento

 jQuery(window).resizeDelayed( func, delay, id ); // delay and id are optional 

Remova a function (declarando seu ID) adicionada anteriormente

 jQuery(window).resizeDelayed( false, id ); 

Remova todas as funções

 jQuery(window).resizeDelayed( false ); 

USO:

 // ADD SOME FUNCTIONS TO RESIZE EVENT jQuery(window).resizeDelayed( function(){ console.log( 'first event - should run after 0.4 seconds'); }, 400, 'id-first-event' ); jQuery(window).resizeDelayed( function(){ console.log('second event - should run after 1.5 seconds'); }, 1500, 'id-second-event' ); jQuery(window).resizeDelayed( function(){ console.log( 'third event - should run after 3.0 seconds'); }, 3000, 'id-third-event' ); // LETS DELETE THE SECOND ONE jQuery(window).resizeDelayed( false, 'id-second-event' ); // LETS ADD ONE WITH AUTOGENERATED ID(THIS COULDNT BE DELETED LATER) AND DEFAULT TIMEOUT (500ms) jQuery(window).resizeDelayed( function(){ console.log('newest event - should run after 0.5 second'); } ); // LETS CALL RESIZE EVENT MANUALLY MULTIPLE TIMES (OR YOU CAN RESIZE YOUR BROWSER WINDOW) TO SEE WHAT WILL HAPPEN jQuery(window).resize().resize().resize().resize().resize().resize().resize(); 

Saída de uso:

 first event - should run after 0.4 seconds newest event - should run after 0.5 second third event - should run after 3.0 seconds 

PLUGAR:

 jQuery.fn.resizeDelayed = (function(){ // >>> THIS PART RUNS ONLY ONCE - RIGHT NOW var rd_funcs = [], rd_counter = 1, foreachResizeFunction = function( func ){ for( var index in rd_funcs ) { func(index); } }; // REGISTER JQUERY RESIZE EVENT HANDLER jQuery(window).resize(function() { // SET/RESET TIMEOUT ON EACH REGISTERED FUNCTION foreachResizeFunction(function(index){ // IF THIS FUNCTION IS MANUALLY DISABLED ( by calling jQuery(window).resizeDelayed(false, 'id') ), // THEN JUST CONTINUE TO NEXT ONE if( rd_funcs[index] === false ) return; // CONTINUE; // IF setTimeout IS ALREADY SET, THAT MEANS THAT WE SHOULD RESET IT BECAUSE ITS CALLED BEFORE DURATION TIME EXPIRES if( rd_funcs[index].timeout !== false ) clearTimeout( rd_funcs[index].timeout ); // SET NEW TIMEOUT BY RESPECTING DURATION TIME rd_funcs[index].timeout = setTimeout( rd_funcs[index].func, rd_funcs[index].delay ); }); }); // < << THIS PART RUNS ONLY ONCE - RIGHT NOW // RETURN THE FUNCTION WHICH JQUERY SHOULD USE WHEN jQuery(window).resizeDelayed(...) IS CALLED return function( func_or_false, delay_or_id, id ){ // FIRST PARAM SHOULD BE SET! if( typeof func_or_false == "undefined" ){ console.log( 'jQuery(window).resizeDelayed(...) REQUIRES AT LEAST 1 PARAMETER!' ); return this; // RETURN JQUERY OBJECT } // SHOULD WE DELETE THE EXISTING FUNCTION(S) INSTEAD OF CREATING A NEW ONE? if( func_or_false == false ){ // DELETE ALL REGISTERED FUNCTIONS? if( typeof delay_or_id == "undefined" ){ // CLEAR ALL setTimeout's FIRST foreachResizeFunction(function(index){ if( typeof rd_funcs[index] != "undefined" && rd_funcs[index].timeout !== false ) clearTimeout( rd_funcs[index].timeout ); }); rd_funcs = []; return this; // RETURN JQUERY OBJECT } // DELETE ONLY THE FUNCTION WITH SPECIFIC ID? else if( typeof rd_funcs[delay_or_id] != "undefined" ){ // CLEAR setTimeout FIRST if( rd_funcs[delay_or_id].timeout !== false ) clearTimeout( rd_funcs[delay_or_id].timeout ); rd_funcs[delay_or_id] = false; return this; // RETURN JQUERY OBJECT } } // NOW, FIRST PARAM MUST BE THE FUNCTION if( typeof func_or_false != "function" ) return this; // RETURN JQUERY OBJECT // SET THE DEFAULT DELAY TIME IF ITS NOT ALREADY SET if( typeof delay_or_id == "undefined" || isNaN(delay_or_id) ) delay_or_id = 500; // SET THE DEFAULT ID IF ITS NOT ALREADY SET if( typeof id == "undefined" ) id = rd_counter; // ADD NEW FUNCTION TO RESIZE EVENT rd_funcs[id] = { func : func_or_false, delay: delay_or_id, timeout : false }; rd_counter++; return this; // RETURN JQUERY OBJECT } })(); 

Declarar ouvinte globalmente atrasado:

 var resize_timeout; $(window).on('resize orientationchange', function(){ clearTimeout(resize_timeout); resize_timeout = setTimeout(function(){ $(window).trigger('resized'); }, 250); }); 

E abaixo, use os ouvintes para o evento resized como você deseja:

 $(window).on('resized', function(){ console.log('resized'); }); 

Supondo que o cursor do mouse deva retornar ao documento após o redimensionamento da janela, podemos criar um comportamento semelhante ao retorno de chamada com o evento onmouseover. Não se esqueça de que esta solução pode não funcionar para canvass ativadas por toque, conforme o esperado.

 var resizeTimer; var resized = false; $(window).resize(function() { clearTimeout(resizeTimer); resizeTimer = setTimeout(function() { if(!resized) { resized = true; $(document).mouseover(function() { resized = false; // do something here $(this).unbind("mouseover"); }) } }, 500); }); 

Funciona para mim. Veja esta solução – https://alvarotrigo.com/blog/firing-resize-event-only-once-when-resizing-is-finished/

 var resizeId; $(window).resize(function() { clearTimeout(resizeId); resizeId = setTimeout(doneResizing, 500); }); function doneResizing(){ //whatever we want to do } 

Dê uma olhada neste artigo CSS-Tricks. Eles fazem uso de um recurso chamado debounce. Só é executado quando o redimensionamento da janela pára.

Link do artigo CSS-Truques

Isto é o que eu implementei:

$ (janela) .resize (function () {setTimeout (someFunction, 500);});

podemos definir [clear the setTimeout][1] se esperamos resize para acontecer menos de 500ms

Boa sorte…