Also benutze ich momentan so etwas wie:
$(window).resize(function(){resizedw();});
Dies wird jedoch viele Male aufgerufen, während der Größenänderungsprozess fortgesetzt wird. Ist es möglich, ein Ereignis zu erfassen, wenn es endet?
Ich hatte Glück mit der folgenden Empfehlung: http://forum.jquery.com/topic/the-resizeend-event
Hier ist der Code, damit Sie nicht den Link und die Quelle seines Posts durchsuchen müssen:
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');
}
}
Danke sime.vidas für den Code!
Sie können setTimeout()
und clearTimeout()
verwenden
function resizedw(){
// Haven't resized in 100ms!
}
var doit;
window.onresize = function(){
clearTimeout(doit);
doit = setTimeout(resizedw, 100);
};
Codebeispiel auf jsfiddle .
Dies ist der Code, den ich nach @ Mark Coleman Antwort schreibe:
$(window).resize(function() {
clearTimeout(window.resizedFinished);
window.resizedFinished = setTimeout(function(){
console.log('Resized finished.');
}, 250);
});
Danke Markus!
Internet Explorer bietet ein resizeEnd -Ereignis. Andere Browser lösen das Größenänderungsereignis mehrmals aus, während Sie die Größe ändern.
Es gibt hier andere großartige Antworten, die zeigen, wie setTimeout und die Methoden . Throttle , . Debounce von lodash und Underscore verwendet werden, also ich Erwähnen wir Ben Almans jQuery-Plug-in mit Gaspedal, das das schafft, wonach Sie suchen.
Angenommen, Sie haben diese Funktion, die Sie nach einer Größenänderung auslösen möchten:
function onResize() {
console.log("Resize just happened!");
};
Beispiel für eine Drosselklappe
Im folgenden Beispiel wird onResize()
während einer Fenstergrößenänderung nur einmal alle 250 Millisekunden aufgerufen.
$(window).resize( $.throttle( 250, onResize) );
Debounce-Beispiel
Im folgenden Beispiel wird onResize()
nur einmal am Ende einer Fenstergrößenänderung aufgerufen. Dies führt zu dem gleichen Ergebnis, das @Mark in seiner Antwort präsentiert.
$(window).resize( $.debounce( 250, onResize) );
Es gibt eine elegante Lösung, die nderscore.js verwendet. Wenn Sie sie also in Ihrem Projekt verwenden, können Sie Folgendes tun:
$( window ).resize( _.debounce( resizedw, 500 ) );
Das sollte reichen :) Aber wenn du mehr darüber lesen möchtest, kannst du meinen Blog-Beitrag lesen - http://rifatnabi.com/post/detect-end-of-jquery-resize-event-using-underscore-debounce(Deadlink)
Sie können eine Referenz-ID für jedes setInterval oder setTimeout speichern. So was:
var loop = setInterval(func, 30);
// some time later clear the interval
clearInterval(loop);
Um dies ohne eine "globale" Variable zu tun, können Sie der Funktion selbst eine lokale Variable hinzufügen. Ex:
$(window).resize(function() {
clearTimeout(this.id);
this.id = setTimeout(doneResizing, 500);
});
function doneResizing(){
$("body").append("<br/>done!");
}
Eine Lösung ist, jQuery um eine Funktion zu erweitern, z. B .: 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));
});
};
Beispielnutzung:
$(window).resized(myHandler, 300);
Sie können setTimeout()
und clearTimeout()
in Verbindung mit jQuery.data
:
$(window).resize(function() {
clearTimeout($.data(this, 'resizeTimer'));
$.data(this, 'resizeTimer', setTimeout(function() {
//do something
alert("Haven't resized in 200ms!");
}, 200));
});
Update
Ich habe eine Erweiterung geschrieben, um den Standard-Event-Handler on
(& bind
) von jQuery zu verbessern. Es hängt eine Ereignishandlerfunktion für ein oder mehrere Ereignisse an die ausgewählten Elemente an, wenn das Ereignis für ein bestimmtes Intervall nicht ausgelöst wurde. Dies ist nützlich, wenn Sie einen Rückruf erst nach einer Verzögerung auslösen möchten, z. B. nach dem Größenänderungsereignis. 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));
Verwenden Sie es wie jeden anderen on
oder bind
-Ereignishandler, mit der Ausnahme, dass Sie als letztes einen zusätzlichen Parameter übergeben können:
$(window).on('resize', function(e) {
console.log(e.type + '-event was 200ms not triggered');
}, 200);
Mark Colemans Antwort ist sicherlich weitaus besser als die ausgewählte Antwort. Wenn Sie jedoch die globale Variable für die Zeitüberschreitungs-ID (die Variable doit
in Marks Antwort) vermeiden möchten, können Sie eine der folgenden Aktionen ausführen:
(1) Verwenden Sie einen sofort aufgerufenen Funktionsausdruck (IIFE), um einen Abschluss zu erstellen.
$(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) Verwenden Sie eine Eigenschaft der Event-Handler-Funktion.
$(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);
});
Dies ist eine Modifikation von Dolans Code oben. Ich habe eine Funktion hinzugefügt, die die Fenstergröße zu Beginn der Größenänderung überprüft und mit der Größe am Ende der Größenänderung vergleicht, wenn die Größe entweder größer oder kleiner als der Rand ist ( zB 1000) dann wird nachgeladen.
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;
}
ich habe selbst eine kleine Wrapper-Funktion geschrieben ...
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);
});
};
Hier ist die Verwendung:
var testFn = function(arg1, arg2) {
console.log('[testFn] arg1: '+arg1);
console.log('[testFn] arg2: '+arg2);
};
// document ready
$(function() {
onResize(testFn, 'argument1', 'argument2');
});
Hier ist SEHR einfaches Skript, um sowohl ein 'resizestart'- als auch ein' resizeend'-Ereignis für das Fensterobjekt auszulösen.
Es ist nicht nötig, sich mit Daten und Uhrzeiten zu beschäftigen.
Die Variable d
gibt die Anzahl der Millisekunden zwischen Größenänderungsereignissen an, bevor das Größenänderungsendereignis ausgelöst wird. Sie können damit spielen, um die Empfindlichkeit des Endereignisses zu ändern.
Um diese Ereignisse anzuhören, müssen Sie nur Folgendes tun:
resizestart: $(window).on('resizestart', function(event){console.log('Resize Start!');});
größe ändern: $(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));
Nun, für den Fenstermanager ist jedes Größenänderungsereignis eine eigene Meldung mit einem unterschiedlichen Anfang und Ende. Technisch gesehen ist es also bei jeder Größenänderung des Fensters . das Ende.
Vielleicht möchten Sie Ihre Fortsetzung verzögern? Hier ist ein Beispiel.
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(){
//...
});
Ich weiß nicht, ob mein Code für andere funktioniert, aber es macht wirklich einen tollen Job für mich. Ich bin auf diese Idee gekommen, als ich Dolan Antenucci-Code analysiert habe, da seine Version für mich nicht geeignet ist und ich hoffe wirklich, dass sie jemandem hilft.
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);
}
das hat bei mir funktioniert, da ich keine Plugins verwenden wollte.
$(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();
});
Bei einer Größenänderung des Fensters rufen Sie "setFn" auf, das die Breite des Fensters abruft und als "originalWindowSize" speichert. Rufen Sie dann "checkFn" auf, das nach 500 ms (oder Ihrer Präferenz) die aktuelle Fenstergröße erhält und das Original mit der aktuellen vergleicht. Wenn diese nicht identisch sind, wird die Größe des Fensters immer noch geändert. Vergessen Sie nicht, Konsolenmeldungen in der Produktion zu entfernen, und (optional) kann "setFn" selbstausführend machen.
Ich habe eine Funktion geschrieben, die eine Funktion übergibt, wenn sie in ein Größenänderungsereignis eingeschlossen wird. Es wird ein Intervall verwendet, damit die Größenänderung nicht ständig Zeitüberschreitungsereignisse erzeugt. Auf diese Weise kann unabhängig vom Größenänderungsereignis ein anderer Protokolleintrag ausgeführt werden, der in der Produktion entfernt werden soll.
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");
}
}
da die ausgewählte antwort nicht funktioniert hat .. und wenn du jquery nicht verwendest, ist hier eine einfache drosselfunktion mit einem beispiel wie man sie mit fenstergrößenänderung benutzt
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();
}
Das ist, was ich benutze, um wiederholte Aktionen zu verzögern. Es kann an mehreren Stellen in Ihrem Code aufgerufen werden:
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);
};
};
Verwendungszweck:
$(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...
}
Ich habe eine Funktion implementiert, die zwei Ereignisse auf dem Benutzer-DOM-Element auslöst:
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") );
};
Eine bessere Alternative, die auch von mir erstellt wurde, ist hier: https://stackoverflow.com/a/23692008/28296 (unterstützt " Funktionen löschen ")
Ich habe diese einfache Funktion für die Behandlung von Verzögerungen bei der Ausführung geschrieben, die in jQuery .scroll () und .resize () nützlich ist. Daher wird callback_f nur einmal für eine bestimmte ID-Zeichenfolge ausgeführt.
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);
});
Dies funktionierte für das, was ich in Chrom zu tun versuchte. Dadurch wird der Rückruf erst 200ms nach dem letzten Größenänderungsereignis ausgelöst.