Bu yüzden şu anda bir şey kullanıyorum:
$(window).resize(function(){resizedw();});
Ancak yeniden boyutlandırma işlemi devam ederken bu birçok kez çağrılır. Bir etkinliği sona erdiğinde yakalamak mümkün müdür?
Bu yüzden şu anda bir şey kullanıyorum:
$(window).resize(function(){resizedw();});
Ancak yeniden boyutlandırma işlemi devam ederken bu birçok kez çağrılır. Bir etkinliği sona erdiğinde yakalamak mümkün müdür?
Yanıtlar:
Aşağıdaki öneriyle şansım vardı: http://forum.jquery.com/topic/the-resizeend-event
İşte kodu, yazısının bağlantısını ve kaynağını incelemek zorunda değilsiniz:
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');
}
}
Kod için teşekkürler sime.vidas!
new Date(-1E12)
- yani JSLint kullanımı hakkında uyarır 00
.
rtime: Date; .... if (+new Date() - +rtime < delta)
ve daktiloda resizeend fonksiyonunun ok fonksiyonu olması gerekir resizeend=()=>
. Çünkü resizeend fonksiyonunda this
pencere nesnesine başvurunuz.
Kullanabilirsiniz setTimeout()
veclearTimeout()
function resizedw(){
// Haven't resized in 100ms!
}
var doit;
window.onresize = function(){
clearTimeout(doit);
doit = setTimeout(resizedw, 100);
};
Jsfiddle'da kod örneği .
$(document)
, fare algılaması Microsoft Windows ve Internet Explorer'ın savunmasız sürümlerini çalıştıran kullanıcılarla sınırlı olacaktır: iedataleak.spider.io/demo
@Mark Coleman cevabına göre yazdığım kod:
$(window).resize(function() {
clearTimeout(window.resizedFinished);
window.resizedFinished = setTimeout(function(){
console.log('Resized finished.');
}, 250);
});
Teşekkürler Mark!
resizeTimer
genel bir değişkendir, yani hayır olarak tanımlanır window
, bu yüzden burada olduğu gibi aynıdır, değişkeni harici olarak tanımlamanız gerekmediğinden sadece bu örnek daha iyidir. ve bu değişkeni window
nesneye eklemek de mantıklıdır çünkü olay dinleyicisinin bağlandığı Nesne budur.
Internet Explorer bir resizeEnd olayı sağlar. Diğer tarayıcılar, yeniden boyutlandırırken yeniden boyutlandırma etkinliğini birçok kez tetikler.
Burada setTimeout ve .throttle'ın nasıl kullanılacağını gösteren başka harika cevaplar var ,Lodash ve alt çizgiden .debounce yöntemleri, bu yüzden Ben Alman'ın gaz-debounce jQuery eklentisinden bahsedeceğim .
Yeniden boyutlandırma sonrasında tetiklemek istediğiniz bu işleve sahip olduğunuzu varsayalım:
function onResize() {
console.log("Resize just happened!");
};
Gaz Örneği
Aşağıdaki örnekte, onResize()
pencere yeniden boyutlandırması sırasında her 250 milisaniyede bir çağrılır.
$(window).resize( $.throttle( 250, onResize) );
Arındırma Örneği
Aşağıdaki örnekte, onResize()
bir pencereyi yeniden boyutlandırma eyleminin sonunda yalnızca bir kez çağrılacaktır. Bu, @ Mark'ın cevabında sunduğu aynı sonucu elde eder.
$(window).resize( $.debounce( 250, onResize) );
Underscore.js'yi kullanan zarif bir çözüm var. Yani, projenizde kullanıyorsanız aşağıdakileri yapabilirsiniz -
$( window ).resize( _.debounce( resizedw, 500 ) );
Bu yeterli olmalı :) Ancak, bunun hakkında daha fazla bilgi edinmek istiyorsanız, blog yayınımı kontrol edebilirsiniz - http://rifatnabi.com/post/detect-end-of-jquery-resize-event-using-underscore -debounce (deadlink)
lodash
bu eklemek de isteyen
Bir çözüm jQuery'yi bir işlevle genişletmektir, örneğin: 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));
});
};
Örnek kullanım:
$(window).resized(myHandler, 300);
Herhangi bir setInterval veya setTimeout'a bir referans kimliği depolayabilirsiniz. Bunun gibi:
var loop = setInterval(func, 30);
// some time later clear the interval
clearInterval(loop);
Bunu "global" değişken olmadan yapmak için işlevin kendisine yerel bir değişken ekleyebilirsiniz. Ör:
$(window).resize(function() {
clearTimeout(this.id);
this.id = setTimeout(doneResizing, 500);
});
function doneResizing(){
$("body").append("<br/>done!");
}
Şunlarla birlikte setTimeout()
ve aşağıdakileri kullanabilirsiniz :clearTimeout()
jQuery.data
$(window).resize(function() {
clearTimeout($.data(this, 'resizeTimer'));
$.data(this, 'resizeTimer', setTimeout(function() {
//do something
alert("Haven't resized in 200ms!");
}, 200));
});
Güncelleme
JQuery varsayılan (& ) -event-handler geliştirmek için bir uzantı yazdım . Olay belirli bir aralık için tetiklenmediyse, seçilen öğelere bir veya daha fazla olay için bir olay işleyici işlevi ekler. Bu, yalnızca resize olayı gibi bir gecikmeden sonra veya başka bir şekilde geri arama yapmak istiyorsanız yararlıdır.
https://github.com/yckart/jquery.unevent.json
bind
;(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));
Son olarak fazladan bir parametre iletebilmeniz dışında, diğer on
veya bind
-event işleyicileri gibi kullanın :
$(window).on('resize', function(e) {
console.log(e.type + '-event was 200ms not triggered');
}, 200);
Yeniden boyutlandırmanın sonunda bir işlevi yürütmek için iki çağrı arasındaki delta süresini hesaplamaktan çok daha basit bir yöntem vardır, bunu şu şekilde yapın:
var resizeId;
$(window).resize(function() {
clearTimeout(resizeId);
resizeId = setTimeout(resizedEnded, 500);
});
function resizedEnded(){
...
}
Ve Angular2 için eşdeğer :
private resizeId;
@HostListener('window:resize', ['$event'])
onResized(event: Event) {
clearTimeout(this.resizeId);
this.resizeId = setTimeout(() => {
// Your callback method here.
}, 500);
}
Açısal yöntem için, kapsamı korumak için içindeki () => { }
gösterimi kullanın setTimeout
, aksi takdirde herhangi bir işlev çağrısı veya kullanım yapamazsınız this
.
Bu yukarıdaki Dolan kodunda yapılan bir değişikliktir, yeniden boyutlandırmanın başlangıcında pencere boyutunu kontrol eden ve boyutun kenar boşluğundan daha büyük veya daha küçük olması durumunda yeniden boyutlandırmanın sonundaki boyutla karşılaştıran bir özellik ekledim ( örneğin 1000) yeniden yüklenir.
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;
}
Mark Coleman'ın cevabı kesinlikle seçilen cevaptan çok daha iyidir, ancak zaman aşımı kimliğinin global değişkeninden ( doit
Mark'ın cevabındaki değişken) kaçınmak istiyorsanız , aşağıdakilerden birini yapabilirsiniz:
(1) Bir kapatma oluşturmak için hemen çağrılan bir işlev ifadesi (IIFE) kullanın.
$(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) Olay işleyici işlevinin bir özelliğini kullanın.
$(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);
});
Ben kendi üzerine bir litte sarıcı işlevi yazdı ...
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);
});
};
İşte kullanımı:
var testFn = function(arg1, arg2) {
console.log('[testFn] arg1: '+arg1);
console.log('[testFn] arg2: '+arg2);
};
// document ready
$(function() {
onResize(testFn, 'argument1', 'argument2');
});
(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(){
//...
});
Eh, bildiğim kadarıyla pencere yöneticisi söz konusu olduğunda, her boyutlandırma olay kendi mesaj yani teknik olarak pencere yeniden boyutlandırılır her zaman, o ayrı bir başı ve sonu ile olan bir uç.
Bunu söyledikten sonra, belki de devamınızı geciktirmek istersiniz? İşte bir örnek.
var t = -1;
function doResize()
{
document.write('resize');
}
$(document).ready(function(){
$(window).resize(function(){
clearTimeout(t);
t = setTimeout(doResize, 1000);
});
});
İşte pencere nesnesinde hem 'resizestart' hem de 'resizeend' olayını tetiklemek için ÇOK basit komut dosyası var.
Tarih ve saatlerle uğraşmanıza gerek yoktur.
d
Değişken boyutlandırma uç olayı tetiklemeden önce yeniden boyutlandırma olay arasında milisaniye sayısını temsil eder bu son olay ne kadar hassas değiştirmek için bu oynayabilirsiniz.
Bu olayları dinlemek için tek yapmanız gereken:
resizestart: $(window).on('resizestart', function(event){console.log('Resize Start!');});
resizeend:
$(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));
Tekrarlanan eylemleri geciktirmek için kullandığım budur, kodunuzda birden fazla yerde çağrılabilir:
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);
};
};
Kullanımı:
$(window).resize(function () {
debounce(function() {
//...
}, 500);
});
seçilen cevap aslında işe yaramadı çünkü .. ve jquery kullanmıyorsanız burada pencere yeniden boyutlandırma ile nasıl kullanılacağına dair bir örnek ile basit bir gaz fonksiyonu
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();
}
Herhangi bir eklenti kullanmak istemediğim için bu benim için çalıştı.
$(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();
});
Pencerenin yeniden boyutunda, pencerenin genişliğini alan ve "originalWindowSize" olarak kaydedilen "setFn" işlevini çağırın. Ardından, 500ms'den sonra (veya tercihiniz) geçerli pencere boyutunu alan ve aynı değilse orijinali akımla karşılaştıran "checkFn" çağırın, pencere yine de yeniden boyutlandırılır. Üretimdeki konsol mesajlarını kaldırmayı unutmayın ve (isteğe bağlı) "setFn" kendi kendini yürütebilir.
var resizeTimer;
$( window ).resize(function() {
if(resizeTimer){
clearTimeout(resizeTimer);
}
resizeTimer = setTimeout(function() {
//your code here
resizeTimer = null;
}, 200);
});
Bu, kromda yapmaya çalıştığım şey için çalıştı. Bu, son yeniden boyutlandırma etkinliğinden 200ms sonrasına kadar geri aramayı tetiklemez.
Benim tarafımdan da oluşturulan daha iyi bir alternatif burada: https://stackoverflow.com/a/23692008/2829600 ("işlevleri sil" işlevini destekler)
Bu basit işlevi jQuery .scroll () ve .resize () içinde yararlı yürütme gecikme işlemek için yazdım Yani callback_f belirli bir kimlik dizesi için sadece bir kez çalışacaktır.
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!
*/
$(window).resize(function() { delay_exec('test1', 30, function() { ... delayed stuff here ... }); });
? Aksi takdirde oldukça temiz kod. Paylaşım için teşekkürler. :)
Kullanıcı DOM öğesinde iki olayı tetikleyen işlevi uyguladım:
Kod:
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") );
};
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...
}
Bilmiyorum benim kod çalışması için diğer ama gerçekten benim için harika bir iş yapmak. Dolan Antenucci kodunu analiz ederek bu fikri anladım çünkü sürümü benim için işe yaramıyor ve umarım birisi için faydalı olacaktır.
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);
}
Herhangi bir resize olayına sarıldığında bir fonksiyonu geçen bir fonksiyon yazdım. Bir aralık kullanır, böylece yeniden boyutlandırma sürekli zaman aşımı olayları oluşturmaz. Bu, üretimde kaldırılması gereken bir günlük girişi dışında resize olayından bağımsız olarak çalışmasını sağlar.
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");
}
}
.one()
sadece tüm yeniden boyutlandırma yapıldıktan sonra tekrar tekrar çalıştıktan sonra yürütmek için kullanarak ekleyin ?