Donc, j'utilise actuellement quelque chose comme:
$(window).resize(function(){resizedw();});
Mais cela est appelé plusieurs fois pendant le processus de redimensionnement. Est-il possible d'attraper un événement à la fin?
J'ai eu de la chance avec la recommandation suivante: http://forum.jquery.com/topic/the-resizeend-event
Voici le code pour que vous n'ayez pas à fouiller dans le lien et la source de son message:
var rtime;
var timeout = false;
var delta = 200;
$(window).resize(function() {
rtime = new Date();
if (timeout === false) {
timeout = true;
setTimeout(resizeend, delta);
}
});
function resizeend() {
if (new Date() - rtime < delta) {
setTimeout(resizeend, delta);
} else {
timeout = false;
alert('Done resizing');
}
}
Merci sime.vidas pour le code!
Vous pouvez utiliser setTimeout()
et clearTimeout()
function resizedw(){
// Haven't resized in 100ms!
}
var doit;
window.onresize = function(){
clearTimeout(doit);
doit = setTimeout(resizedw, 100);
};
Exemple de code sur jsfiddle .
Ceci est le code que j'écris selon la réponse de @Mark Coleman:
$(window).resize(function() {
clearTimeout(window.resizedFinished);
window.resizedFinished = setTimeout(function(){
console.log('Resized finished.');
}, 250);
});
Merci Mark!
Internet Explorer fournit un événement resizeEnd . D'autres navigateurs déclenchent l'événement de redimensionnement plusieurs fois pendant le redimensionnement.
Il existe d’autres bonnes réponses ici qui montrent comment utiliser setTimeout et les méthodes . Throttle , . Debounce de lodash et de soulignement , je mentionnerai donc Ben Alman plugin jQuery throttle-debounce qui accomplit ce que vous recherchez.
Supposons que vous ayez cette fonction à déclencher après un redimensionnement:
function onResize() {
console.log("Resize just happened!");
};
Exemple de papillon
Dans l'exemple suivant, onResize()
ne sera appelé qu'une fois toutes les 250 millisecondes pendant le redimensionnement d'une fenêtre.
$(window).resize( $.throttle( 250, onResize) );
Exemple anti-rebond
Dans l'exemple suivant, onResize()
ne sera appelé qu'une fois à la fin d'une action de redimensionnement de la fenêtre. Cela donne le même résultat que @Mark présente dans sa réponse.
$(window).resize( $.debounce( 250, onResize) );
Il existe une solution élégante utilisant le nderscore.js Ainsi, si vous l’utilisez dans votre projet, vous pouvez effectuer les opérations suivantes:
$( window ).resize( _.debounce( resizedw, 500 ) );
Cela devrait suffire :) Mais, si vous êtes intéressé à en savoir plus à ce sujet, vous pouvez consulter mon blog - http://rifatnabi.com/post/detect-end-of-jquery-resize-event-using-underscore-debounce(lien mort)
Vous pouvez stocker un identifiant de référence pour n’importe quel setInterval ou setTimeout. Comme ça:
var loop = setInterval(func, 30);
// some time later clear the interval
clearInterval(loop);
Pour ce faire sans variable "globale", vous pouvez ajouter une variable locale à la fonction elle-même. Ex:
$(window).resize(function() {
clearTimeout(this.id);
this.id = setTimeout(doneResizing, 500);
});
function doneResizing(){
$("body").append("<br/>done!");
}
Une solution consiste à étendre jQuery avec une fonction, par exemple: resized
$.fn.resized = function (callback, timeout) {
$(this).resize(function () {
var $this = $(this);
if ($this.data('resizeTimeout')) {
clearTimeout($this.data('resizeTimeout'));
}
$this.data('resizeTimeout', setTimeout(callback, timeout));
});
};
Exemple d'utilisation:
$(window).resized(myHandler, 300);
Vous pouvez utiliser setTimeout()
et clearTimeout()
conjointement avec jQuery.data
:
_$(window).resize(function() {
clearTimeout($.data(this, 'resizeTimer'));
$.data(this, 'resizeTimer', setTimeout(function() {
//do something
alert("Haven't resized in 200ms!");
}, 200));
});
_
Mettre à jour
J'ai écrit une extension pour améliorer le comportement par défaut de jQuery on
(& bind
) - gestionnaire d'événements. Il associe une fonction de gestionnaire d'événements pour un ou plusieurs événements aux éléments sélectionnés si l'événement n'a pas été déclenché pour un intervalle donné. Ceci est utile si vous souhaitez déclencher un rappel uniquement après un délai, comme l'événement de redimensionnement, ou autre. https://github.com/yckart/jquery.unevent.js
_;(function ($) {
var methods = { on: $.fn.on, bind: $.fn.bind };
$.each(methods, function(k){
$.fn[k] = function () {
var args = [].slice.call(arguments),
delay = args.pop(),
fn = args.pop(),
timer;
args.Push(function () {
var self = this,
arg = arguments;
clearTimeout(timer);
timer = setTimeout(function(){
fn.apply(self, [].slice.call(arg));
}, delay);
});
return methods[k].apply(this, isNaN(delay) ? arguments : args);
};
});
}(jQuery));
_
Utilisez-le comme n'importe quel autre gestionnaire d'événements on
ou bind
-, sauf que vous pouvez transmettre un paramètre supplémentaire en dernier:
_$(window).on('resize', function(e) {
console.log(e.type + '-event was 200ms not triggered');
}, 200);
_
La réponse de Mark Coleman est certainement bien meilleure que la réponse sélectionnée, mais si vous souhaitez éviter la variable globale pour l'ID de délai d'attente (la variable doit
de la réponse de Mark), vous pouvez effectuer l'une des opérations suivantes:
(1) Utilisez une expression de fonction immédiatement appelée (IIFE) pour créer une fermeture.
$(window).resize((function() { // This function is immediately invoked
// and returns the closure function.
var timeoutId;
return function() {
clearTimeout(timeoutId);
timeoutId = setTimeout(function() {
timeoutId = null; // You could leave this line out.
// Code to execute on resize goes here.
}, 100);
};
})());
(2) Utilisez une propriété de la fonction de gestionnaire d'événements.
$(window).resize(function() {
var thisFunction = arguments.callee;
clearTimeout(thisFunction.timeoutId);
thisFunction.timeoutId = setTimeout(function() {
thisFunction.timeoutId = null; // You could leave this line out.
// Code to execute on resize goes here.
}, 100);
});
Ceci est une modification du code de Dolan ci-dessus, j'ai ajouté une fonctionnalité qui vérifie la taille de la fenêtre au début du redimensionnement et la compare à la taille à la fin du redimensionnement, si la taille est plus grande ou plus petite que la marge ( par exemple 1000) puis il recharge.
var rtime = new Date(1, 1, 2000, 12,00,00);
var timeout = false;
var delta = 200;
var windowsize = $window.width();
var windowsizeInitial = $window.width();
$(window).on('resize',function() {
windowsize = $window.width();
rtime = new Date();
if (timeout === false) {
timeout = true;
setTimeout(resizeend, delta);
}
});
function resizeend() {
if (new Date() - rtime < delta) {
setTimeout(resizeend, delta);
return false;
} else {
if (windowsizeInitial > 1000 && windowsize > 1000 ) {
setTimeout(resizeend, delta);
return false;
}
if (windowsizeInitial < 1001 && windowsize < 1001 ) {
setTimeout(resizeend, delta);
return false;
} else {
timeout = false;
location.reload();
}
}
windowsizeInitial = $window.width();
return false;
}
j'ai écrit une petite fonction wrapper moi-même ...
onResize = function(fn) {
if(!fn || typeof fn != 'function')
return 0;
var args = Array.prototype.slice.call(arguments, 1);
onResize.fnArr = onResize.fnArr || [];
onResize.fnArr.Push([fn, args]);
onResize.loop = function() {
$.each(onResize.fnArr, function(index, fnWithArgs) {
fnWithArgs[0].apply(undefined, fnWithArgs[1]);
});
};
$(window).on('resize', function(e) {
window.clearTimeout(onResize.timeout);
onResize.timeout = window.setTimeout("onResize.loop();", 300);
});
};
Voici l'usage:
var testFn = function(arg1, arg2) {
console.log('[testFn] arg1: '+arg1);
console.log('[testFn] arg2: '+arg2);
};
// document ready
$(function() {
onResize(testFn, 'argument1', 'argument2');
});
Voici un script TRÈS simple pour déclencher à la fois un événement 'resizestart' et 'resizeend' sur l'objet window.
Il n'est pas nécessaire de perdre du temps avec les dates et les heures.
La variable d
représente le nombre de millisecondes entre les événements de redimensionnement avant de déclencher l'événement de fin de redimensionnement. Vous pouvez utiliser cette variable pour modifier le niveau de sensibilité de l'événement de fin.
Pour écouter ces événements, il vous suffit de:
resizestart: $(window).on('resizestart', function(event){console.log('Resize Start!');});
redimensionner: $(window).on('resizeend', function(event){console.log('Resize End!');});
(function ($) {
var d = 250, t = null, e = null, h, r = false;
h = function () {
r = false;
$(window).trigger('resizeend', e);
};
$(window).on('resize', function (event) {
e = event || e;
clearTimeout(t);
if (!r) {
$(window).trigger('resizestart', e);
r = true;
}
t = setTimeout(h, d);
});
}(jQuery));
En ce qui concerne le gestionnaire de fenêtres, chaque événement de redimensionnement est son propre message, avec un début et une fin distincts. Donc techniquement, chaque fois que la fenêtre est redimensionnée, il est la fin.
Cela dit, vous souhaitez peut-être fixer un délai à votre poursuite? Voici un exemple.
var t = -1;
function doResize()
{
document.write('resize');
}
$(document).ready(function(){
$(window).resize(function(){
clearTimeout(t);
t = setTimeout(doResize, 1000);
});
});
(function(){
var special = jQuery.event.special,
uid1 = 'D' + (+new Date()),
uid2 = 'D' + (+new Date() + 1);
special.resizestart = {
setup: function() {
var timer,
handler = function(evt) {
var _self = this,
_args = arguments;
if (timer) {
clearTimeout(timer);
} else {
evt.type = 'resizestart';
jQuery.event.handle.apply(_self, _args);
}
timer = setTimeout( function(){
timer = null;
}, special.resizestop.latency);
};
jQuery(this).bind('resize', handler).data(uid1, handler);
},
teardown: function(){
jQuery(this).unbind( 'resize', jQuery(this).data(uid1) );
}
};
special.resizestop = {
latency: 200,
setup: function() {
var timer,
handler = function(evt) {
var _self = this,
_args = arguments;
if (timer) {
clearTimeout(timer);
}
timer = setTimeout( function(){
timer = null;
evt.type = 'resizestop';
jQuery.event.handle.apply(_self, _args);
}, special.resizestop.latency);
};
jQuery(this).bind('resize', handler).data(uid2, handler);
},
teardown: function() {
jQuery(this).unbind( 'resize', jQuery(this).data(uid2) );
}
};
})();
$(window).bind('resizestop',function(){
//...
});
Je ne sais pas si mon code fonctionne pour d’autres, mais c’est vraiment un excellent travail pour moi. J'ai eu cette idée en analysant le code de Dolan Antenucci parce que sa version ne fonctionne pas pour moi et j'espère vraiment que cela sera utile à quelqu'un.
var tranStatus = false;
$(window).resizeend(200, function(){
$(".cat-name, .category").removeAttr("style");
//clearTimeout(homeResize);
$("*").one("webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend",function(event) {
tranStatus = true;
});
processResize();
});
function processResize(){
homeResize = setInterval(function(){
if(tranStatus===false){
console.log("not yet");
$("*").one("webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend",function(event) {
tranStatus = true;
});
}else{
text_height();
clearInterval(homeResize);
}
},200);
}
cela a fonctionné pour moi car je ne voulais utiliser aucun plugin.
$(window).resize(function() {
var originalWindowSize = 0;
var currentWidth = 0;
var setFn = function () {
originalWindowSize = $(window).width();
};
var checkFn = function () {
setTimeout(function () {
currentWidth = $(window).width();
if (currentWidth === originalWindowSize) {
console.info("same? = yes")
// execute code
} else {
console.info("same? = no");
// do nothing
}
}, 500)
};
setFn();
checkFn();
});
Lors du redimensionnement de la fenêtre, appelez "setFn" qui obtient la largeur de la fenêtre et enregistre sous le nom "originalWindowSize". Ensuite, appelez "checkFn" qui après 500 ms (ou votre préférence) obtient la taille de la fenêtre actuelle et compare l'original au texte actuel. S'ils ne sont pas identiques, la fenêtre est toujours en cours de redimensionnement. N'oubliez pas de supprimer les messages de la console en production et (optionnel) peut rendre "setFn" automatique.
J'ai écrit une fonction qui passe à une fonction lorsqu'elle est encapsulée dans un événement de redimensionnement. Il utilise un intervalle pour que le redimensionnement ne crée même pas constamment des événements de délai d'expiration. Cela lui permet de fonctionner indépendamment de l'événement de redimensionnement autre qu'une entrée de journal qui devrait être supprimée en production.
https://github.com/UniWrighte/resizeOnEnd/blob/master/resizeOnEnd.js
$(window).resize(function(){
//call to resizeEnd function to execute function on resize end.
//can be passed as function name or anonymous function
resizeEnd(function(){
});
});
//global variables for reference outside of interval
var interval = null;
var width = $(window).width();
var numi = 0; //can be removed in production
function resizeEnd(functionCall){
//check for null interval
if(!interval){
//set to new interval
interval = setInterval(function(){
//get width to compare
width2 = $(window).width();
//if stored width equals new width
if(width === width2){
//clear interval, set to null, and call passed function
clearInterval(interval);
interval = null; //precaution
functionCall();
}
//set width to compare on next interval after half a second
width = $(window).width();
}, 500);
}else{
//logging that should be removed in production
console.log("function call " + numi++ + " and inteval set skipped");
}
}
puisque la réponse sélectionnée ne fonctionnait pas réellement .. et si vous n'utilisez pas jquery, voici une simple fonction de commande avec un exemple d'utilisation de cette fonction avec le redimensionnement de la fenêtre
function throttle(end,delta) {
var base = this;
base.wait = false;
base.delta = 200;
base.end = end;
base.trigger = function(context) {
//only allow if we aren't waiting for another event
if ( !base.wait ) {
//signal we already have a resize event
base.wait = true;
//if we are trying to resize and we
setTimeout(function() {
//call the end function
if(base.end) base.end.call(context);
//reset the resize trigger
base.wait = false;
}, base.delta);
}
}
};
var windowResize = new throttle(function() {console.log('throttle resize');},200);
window.onresize = function(event) {
windowResize.trigger();
}
C’est ce que j’utilise pour retarder les actions répétées, il peut être appelé à plusieurs endroits de votre code:
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);
};
};
Usage:
$(window).resize(function () {
debounce(function() {
//...
}, 500);
});
var flag=true;
var timeloop;
$(window).resize(function(){
rtime=new Date();
if(flag){
flag=false;
timeloop=setInterval(function(){
if(new Date()-rtime>100)
myAction();
},100);
}
})
function myAction(){
clearInterval(timeloop);
flag=true;
//any other code...
}
J'ai implémenté une fonction qui déclenche deux événements sur l'élément DOM de l'utilisateur:
Code:
var resizeEventsTrigger = (function () {
function triggerResizeStart($el) {
$el.trigger('resizestart');
isStart = !isStart;
}
function triggerResizeEnd($el) {
clearTimeout(timeoutId);
timeoutId = setTimeout(function () {
$el.trigger('resizeend');
isStart = !isStart;
}, delay);
}
var isStart = true;
var delay = 200;
var timeoutId;
return function ($el) {
isStart ? triggerResizeStart($el) : triggerResizeEnd($el);
};
})();
$("#my").on('resizestart', function () {
console.log('resize start');
});
$("#my").on('resizeend', function () {
console.log('resize end');
});
window.onresize = function () {
resizeEventsTrigger( $("#my") );
};
Une meilleure alternative également créée par moi est ici: https://stackoverflow.com/a/23692008/28296 (prend en charge " supprimer des fonctions ")
J'ai écrit cette fonction simple pour gérer le retard d'exécution, utile dans jQuery .scroll () et .resize (). Callback_f ne s'exécutera qu'une fois pour une chaîne d'identifiant spécifique.
function delay_exec( id, wait_time, callback_f ){
// IF WAIT TIME IS NOT ENTERED IN FUNCTION CALL,
// SET IT TO DEFAULT VALUE: 0.5 SECOND
if( typeof wait_time === "undefined" )
wait_time = 500;
// CREATE GLOBAL ARRAY(IF ITS NOT ALREADY CREATED)
// WHERE WE STORE CURRENTLY RUNNING setTimeout() FUNCTION FOR THIS ID
if( typeof window['delay_exec'] === "undefined" )
window['delay_exec'] = [];
// RESET CURRENTLY RUNNING setTimeout() FUNCTION FOR THIS ID,
// SO IN THAT WAY WE ARE SURE THAT callback_f WILL RUN ONLY ONE TIME
// ( ON LATEST CALL ON delay_exec FUNCTION WITH SAME ID )
if( typeof window['delay_exec'][id] !== "undefined" )
clearTimeout( window['delay_exec'][id] );
// SET NEW TIMEOUT AND EXECUTE callback_f WHEN wait_time EXPIRES,
// BUT ONLY IF THERE ISNT ANY MORE FUTURE CALLS ( IN wait_time PERIOD )
// TO delay_exec FUNCTION WITH SAME ID AS CURRENT ONE
window['delay_exec'][id] = setTimeout( callback_f , wait_time );
}
// USAGE
jQuery(window).resize(function() {
delay_exec('test1', 1000, function(){
console.log('1st call to delay "test1" successfully executed!');
});
delay_exec('test1', 1000, function(){
console.log('2nd call to delay "test1" successfully executed!');
});
delay_exec('test1', 1000, function(){
console.log('3rd call to delay "test1" successfully executed!');
});
delay_exec('test2', 1000, function(){
console.log('1st call to delay "test2" successfully executed!');
});
delay_exec('test3', 1000, function(){
console.log('1st call to delay "test3" successfully executed!');
});
});
/* RESULT
3rd call to delay "test1" successfully executed!
1st call to delay "test2" successfully executed!
1st call to delay "test3" successfully executed!
*/
var resizeTimer;
$( window ).resize(function() {
if(resizeTimer){
clearTimeout(resizeTimer);
}
resizeTimer = setTimeout(function() {
//your code here
resizeTimer = null;
}, 200);
});
Cela a fonctionné pour ce que j'essayais de faire en chrome. Cela ne déclenchera le rappel que 200 ms après le dernier événement de redimensionnement.