มีวิธีล้างเวลาทั้งหมดออกจากหน้าต่างที่กำหนดหรือไม่? ฉันคิดว่าการหมดเวลาถูกเก็บไว้ที่ใดที่หนึ่งในwindow
วัตถุ แต่ไม่สามารถยืนยันได้
ยินดีต้อนรับโซลูชันข้ามเบราว์เซอร์ใด ๆ
มีวิธีล้างเวลาทั้งหมดออกจากหน้าต่างที่กำหนดหรือไม่? ฉันคิดว่าการหมดเวลาถูกเก็บไว้ที่ใดที่หนึ่งในwindow
วัตถุ แต่ไม่สามารถยืนยันได้
ยินดีต้อนรับโซลูชันข้ามเบราว์เซอร์ใด ๆ
คำตอบ:
พวกเขาไม่ได้อยู่ในวัตถุหน้าต่าง แต่มีรหัสซึ่ง (afaik) เป็นจำนวนเต็มติดต่อกัน
ดังนั้นคุณสามารถล้างการหมดเวลาทั้งหมดได้ดังนี้:
var id = window.setTimeout(function() {}, 0);
while (id--) {
window.clearTimeout(id); // will do nothing if no timeout with id is present
}
ฉันคิดว่าวิธีที่ง่ายที่สุดในการทำให้สำเร็จคือการจัดเก็บตัวsetTimeout
ระบุทั้งหมดไว้ในอาร์เรย์เดียวซึ่งคุณสามารถวนซ้ำไปยังclearTimeout()
ทั้งหมดได้อย่างง่ายดาย
var timeouts = [];
timeouts.push(setTimeout(function(){alert(1);}, 200));
timeouts.push(setTimeout(function(){alert(2);}, 300));
timeouts.push(setTimeout(function(){alert(3);}, 400));
for (var i=0; i<timeouts.length; i++) {
clearTimeout(timeouts[i]);
}
ฉันมีเพิ่มเติมจากคำตอบของ Pumbaa80ที่อาจเป็นประโยชน์สำหรับผู้ที่พัฒนา IE รุ่นเก่า
ใช่เบราว์เซอร์หลักทั้งหมดใช้รหัสการหมดเวลาเป็นจำนวนเต็มติดต่อกัน (ซึ่งไม่จำเป็นตามข้อกำหนด ) ตัวเลขเริ่มต้นแตกต่างจากเบราว์เซอร์จากเบราว์เซอร์ ดูเหมือนว่า Opera, Safari, Chrome และ IE> 8 จะเริ่มรหัสหมดเวลาจาก 1 เบราว์เซอร์ที่ใช้ Gecko จาก 2 และ IE <= 8 จากตัวเลขสุ่มบางตัวที่บันทึกไว้อย่างน่าอัศจรรย์ในการรีเฟรชแท็บ คุณสามารถค้นพบตัวเอง
ทั้งหมดนั้นหมายความว่าใน IE <= 8 while (lastTimeoutId--)
วงจรอาจทำงานเกิน 8digits ครั้งและแสดงข้อความ " A script ในหน้านี้ทำให้ Internet Explorer ทำงานช้า " ดังนั้นหากคุณไม่สามารถบันทึกรหัสการหมดเวลาของคุณได้ทั้งหมดหรือไม่ต้องการแทนที่ window.setTimeoutคุณอาจพิจารณาบันทึกรหัสการหมดเวลาครั้งแรกในหน้าและล้างการหมดเวลาจนกว่าจะถึงเวลานั้น
ดำเนินการโค้ดในการโหลดหน้าแรก:
var clearAllTimeouts = (function () {
var noop = function () {},
firstId = window.setTimeout(noop, 0);
return function () {
var lastId = window.setTimeout(noop, 0);
console.log('Removing', lastId - firstId, 'timeout handlers');
while (firstId != lastId)
window.clearTimeout(++firstId);
};
});
จากนั้นล้างการหมดเวลาที่รอดำเนินการทั้งหมดที่อาจถูกกำหนดโดยรหัสต่างประเทศหลายครั้งที่คุณต้องการ
วิธีการจัดเก็บรหัสการหมดเวลาในอาร์เรย์ส่วนกลางและกำหนดวิธีการเพื่อมอบหมายการเรียกใช้ฟังก์ชันไปยังหน้าต่าง
GLOBAL={
timeouts : [],//global timeout id arrays
setTimeout : function(code,number){
this.timeouts.push(setTimeout(code,number));
},
clearAllTimeout :function(){
for (var i=0; i<this.timeouts.length; i++) {
window.clearTimeout(this.timeouts[i]); // clear all the timeouts
}
this.timeouts= [];//empty the id array
}
};
คุณต้องเขียนwindow.setTimeout
เมธอดใหม่และบันทึกรหัสการหมดเวลา
const timeouts = [];
const originalTimeoutFn = window.setTimeout;
window.setTimeout = function(fun, delay) { //this is over-writing the original method
const t = originalTimeoutFn(fn, delay);
timeouts.push(t);
}
function clearTimeouts(){
while(timeouts.length){
clearTimeout(timeouts.pop();
}
}
วางด้านล่างรหัสก่อนสคริปต์อื่น ๆและมันจะสร้างฟังก์ชั่นเสื้อคลุมสำหรับต้นฉบับและsetTimeout
clearTimeout
clearTimeouts
วิธีการใหม่จะถูกเพิ่มเข้าไปในwindow
Object ซึ่งจะช่วยให้สามารถล้างการหมดเวลาทั้งหมด (รอดำเนินการ) ได้ ( ลิงก์ Gist )
คำตอบอื่น ๆ ขาดการสนับสนุนที่สมบูรณ์สำหรับข้อโต้แย้งที่
setTimeout
อาจได้รับ
// isolated layer wrapper (for the local variables)
(function(_W){
var cache = [], // will store all timeouts IDs
_set = _W.setTimeout, // save original reference
_clear = _W.clearTimeout // save original reference
// Wrap original setTimeout with a function
_W.setTimeout = function( CB, duration, arg ){
// also, wrap the callback, so the cache reference will be removed
// when the timeout has reached (fired the callback)
var id = _set(function(){
CB.apply(null, arguments)
removeCacheItem(id)
}, duration || 0, arg)
cache.push( id ) // store reference in the cache array
// id reference must be returned to be able to clear it
return id
}
// Wrap original clearTimeout with a function
_W.clearTimeout = function( id ){
_clear(id)
removeCacheItem(id)
}
// Add a custom function named "clearTimeouts" to the "window" object
_W.clearTimeouts = function(){
console.log("Clearing " + cache.length + " timeouts")
cache.forEach(n => _clear(n))
cache.length = []
}
// removes a specific id from the cache array
function removeCacheItem( id ){
var idx = cache.indexOf(id)
if( idx > -1 )
cache = cache.filter(n => n != id )
}
})(window);
เพื่อความสมบูรณ์ฉันต้องการโพสต์วิธีแก้ปัญหาทั่วไปที่ครอบคลุมทั้งsetTimeout
และsetInterval
.
ดูเหมือนว่าเบราว์เซอร์อาจใช้กลุ่ม ID เดียวกันสำหรับทั้งสอง แต่จากคำตอบบางส่วนของAre clearTimeout และ clearInterval เหมือนกัน? ยังไม่ชัดเจนว่าจะปลอดภัยที่จะพึ่งพาclearTimeout
และclearInterval
ใช้งานฟังก์ชันเดียวกันหรือทำงานตามประเภทตัวจับเวลาตามลำดับเท่านั้น
ดังนั้นเมื่อเป้าหมายคือการฆ่าการหมดเวลาและช่วงเวลาทั้งหมดนี่คือการใช้งานที่อาจมีการป้องกันมากกว่าเล็กน้อยในการใช้งานเมื่อไม่สามารถทดสอบได้ทั้งหมด:
function clearAll(windowObject) {
var id = Math.max(
windowObject.setInterval(noop, 1000),
windowObject.setTimeout(noop, 1000)
);
while (id--) {
windowObject.clearTimeout(id);
windowObject.clearInterval(id);
}
function noop(){}
}
คุณสามารถใช้เพื่อล้างตัวจับเวลาทั้งหมดในหน้าต่างปัจจุบัน:
clearAll(window);
หรือคุณสามารถใช้เพื่อล้างตัวจับเวลาทั้งหมดในiframe
:
clearAll(document.querySelector("iframe").contentWindow);
ฉันใช้ Vue กับ typescript
private setTimeoutN;
private setTimeoutS = [];
public myTimeoutStart() {
this.myTimeoutStop();//stop All my timeouts
this.setTimeoutN = window.setTimeout( () => {
console.log('setTimeout');
}, 2000);
this.setTimeoutS.push(this.setTimeoutN)//add THIS timeout ID in array
}
public myTimeoutStop() {
if( this.setTimeoutS.length > 0 ) {
for (let id in this.setTimeoutS) {
console.log(this.setTimeoutS[id]);
clearTimeout(this.setTimeoutS[id]);
}
this.setTimeoutS = [];//clear IDs array
}
}
นี่มันดึกมากแล้ว ... แต่:
โดยทั่วไป setTimeout / setInterval ID จะเรียงตามลำดับกันดังนั้นเพียงแค่สร้างฟังก์ชันการหมดเวลาจำลองเพื่อให้ได้ ID สูงสุดจากนั้นล้างช่วงเวลาของ ID ทั้งหมดที่ต่ำกว่านั้น
const highestId = window.setTimeout(() => {
for (let i = highestId; i >= 0; i--) {
window.clearInterval(i);
}
}, 0);
ใช้การหมดเวลาส่วนกลางซึ่งฟังก์ชันอื่น ๆ ทั้งหมดของคุณได้มาจากเวลา สิ่งนี้จะทำให้ทุกอย่างทำงานได้เร็วขึ้นและจัดการได้ง่ายขึ้นแม้ว่าจะเพิ่มนามธรรมให้กับโค้ดของคุณก็ตาม
set_timeout
ฟังก์ชันส่วนกลางหรือไม่? คุณสามารถให้รหัสตัวอย่างได้หรือไม่?
เราเพิ่งเผยแพร่แพ็คเกจเพื่อแก้ปัญหานี้
npm install time-events-manager
ด้วยวิธีนี้คุณสามารถดูการหมดเวลาและช่วงเวลาทั้งหมดผ่านtimeoutCollection
& intervalCollection
วัตถุ นอกจากนี้ยังมีremoveAll
ฟังก์ชั่นที่ล้างการหมดเวลา / ช่วงเวลาทั้งหมดทั้งจากคอลเลคชันและเบราว์เซอร์