funcion - JavaScript/JQuery: $(window).resize cómo disparar DESPUÉS de que se complete el cambio de tamaño?
window addeventlistener resize function() (12)
Algunas de las soluciones mencionadas anteriormente no funcionaron para mí, aunque son de uso más general. Alternativamente, he encontrado este que hizo el trabajo en el tamaño de la ventana:
$(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);
});
});
Estoy usando JQuery como tal:
$(window).resize(function() { ... });
Sin embargo, parece que si la persona cambia manualmente el tamaño de las ventanas de su navegador arrastrando el borde de la ventana para hacerla más grande o más pequeña, el evento .resize
arriba se dispara varias veces.
Pregunta: ¿Cómo puedo llamar a una función DESPUÉS de que se complete el tamaño de la ventana del navegador (para que el evento solo se dispare una vez)?
Aquí hay una modificación de la solución de CMS que se puede llamar en múltiples lugares en su 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");
});
La solución de CMS está bien si solo la llama una vez, pero si la llama varias veces, por ejemplo, si diferentes partes de su código configuran devoluciones de llamada separadas para cambiar el tamaño de la ventana, entonces fallará porque comparten la variable del timer
.
Con esta modificación, proporciona un ID único para cada devolución de llamada, y esos ID únicos se utilizan para mantener separados todos los eventos de tiempo de espera.
Complemento simple de jQuery para el evento de cambio de tamaño de ventana retrasado.
SINTAXIS:
Añadir nueva función para redimensionar evento
jQuery(window).resizeDelayed( func, delay, id ); // delay and id are optional
Elimine la función (declarando su ID) agregada anteriormente
jQuery(window).resizeDelayed( false, id );
Eliminar todas las funciones
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();
SALIDA 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
ENCHUFAR:
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
}
})();
Declara oyente globalmente retrasado:
var resize_timeout;
$(window).on(''resize orientationchange'', function(){
clearTimeout(resize_timeout);
resize_timeout = setTimeout(function(){
$(window).trigger(''resized'');
}, 250);
});
Y a continuación, use los oyentes para resized
evento como desee:
$(window).on(''resized'', function(){
console.log(''resized'');
});
En realidad, como sé, no puede realizar algunas acciones exactamente cuando el cambio de tamaño está desactivado, simplemente porque no conoce las acciones de los futuros usuarios. Pero puede asumir el tiempo transcurrido entre dos eventos de cambio de tamaño, por lo que si espera un poco más que este tiempo y no se realiza ningún cambio de tamaño, puede llamar a su función.
La idea es que usamos setTimeout
y es id para guardarla o eliminarla. Por ejemplo, sabemos que el tiempo entre dos eventos de cambio de tamaño es 500 ms, por lo tanto, esperaremos 750 ms.
var a;
$(window).resize(function(){
clearTimeout(a);
a = setTimeout(function(){
// call your function
},750);
});
Esto es lo que he implementado:
$ (window) .resize (function () {setTimeout (someFunction, 500);});
podemos establecer [clear the setTimeout][1]
si esperamos que el cambio de tamaño ocurra en menos de 500ms
Buena suerte...
Muchas gracias a David Walsh, aquí hay una versión de vainilla del subrayado.
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 simple:
var myEfficientFn = debounce(function() {
// All the taxing stuff you do
}, 250);
$(window).on(''resize'', myEfficientFn);
Prefiero crear un evento:
$(window).bind(''resizeEnd'', function() {
//do something, window hasn''t changed size in 500ms
});
Así es como lo creas:
$(window).resize(function() {
if(this.resizeTO) clearTimeout(this.resizeTO);
this.resizeTO = setTimeout(function() {
$(this).trigger(''resizeEnd'');
}, 500);
});
Podría tener esto en un archivo javascript global en algún lugar.
Suponiendo que el cursor del mouse debería volver al documento después del cambio de tamaño de la ventana, podemos crear un comportamiento similar a la devolución de llamada con el evento onmouseover. No olvide que esta solución puede no funcionar para pantallas táctiles como se espera.
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);
});
Utilizo la siguiente función para retrasar acciones repetidas, funcionará para su 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);
});
La función de devolución de llamada que se le pasó, se ejecutará solo cuando se haya realizado la última llamada para demorar después de la cantidad de tiempo especificada; de lo contrario, se reiniciará el temporizador, lo encuentro útil para otros fines, como detectar cuándo el usuario dejó de escribir, etc. ..
Esto funciona para mi. Vea esta solución - 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
}
Si tiene Underscore.js instalado, podría:
$(window).resize(_.debounce(function(){
alert("Resized");
},500));