Có cách nào để xóa mọi lúc mọi nơi khỏi một cửa sổ nhất định không? Tôi cho rằng thời gian chờ được lưu trữ ở đâu đó trong window
đối tượng nhưng không thể xác nhận điều đó.
Mọi giải pháp trình duyệt chéo đều được hoan nghênh.
Có cách nào để xóa mọi lúc mọi nơi khỏi một cửa sổ nhất định không? Tôi cho rằng thời gian chờ được lưu trữ ở đâu đó trong window
đối tượng nhưng không thể xác nhận điều đó.
Mọi giải pháp trình duyệt chéo đều được hoan nghênh.
Câu trả lời:
Chúng không nằm trong đối tượng window, nhưng chúng có id, (afaik) là các số nguyên liên tiếp.
Vì vậy, bạn có thể xóa tất cả thời gian chờ như vậy:
var id = window.setTimeout(function() {}, 0);
while (id--) {
window.clearTimeout(id); // will do nothing if no timeout with id is present
}
Tôi nghĩ rằng cách dễ nhất để thực hiện điều này là lưu trữ tất cả các số setTimeout
nhận dạng trong một mảng, nơi bạn có thể dễ dàng lặp lại clearTimeout()
trên tất cả chúng.
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]);
}
Tôi có một bổ sung cho câu trả lời của Pumbaa80 có thể hữu ích cho ai đó đang phát triển cho các IE cũ.
Có, tất cả các trình duyệt chính đều triển khai id thời gian chờ dưới dạng các số nguyên liên tiếp ( không bắt buộc theo đặc tả ). Thông qua số bắt đầu khác nhau giữa trình duyệt biểu mẫu với trình duyệt. Có vẻ như Opera, Safari, Chrome và IE> 8 bắt đầu id thời gian chờ từ 1, các trình duyệt dựa trên Gecko từ 2 và IE <= 8 từ một số ngẫu nhiên được lưu một cách kỳ diệu khi làm mới tab. Bạn có thể tự mình khám phá .
Tất cả những điều đó xảy ra trong IE <= 8, while (lastTimeoutId--)
chu kỳ có thể chạy hơn 8 ký tự lần và hiển thị thông báo " Tập lệnh trên trang này khiến Internet Explorer chạy chậm ". Vì vậy, nếu bạn không thể lưu tất cả id thời gian chờ của mình hoặc không muốn ghi đè window.setTimeout, bạn có thể cân nhắc lưu id thời gian chờ đầu tiên trên một trang và xóa thời gian chờ cho đến khi nó.
Thực thi mã khi tải trang đầu:
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);
};
});
Và sau đó xóa tất cả thời gian chờ đang chờ xử lý có thể do mã nước ngoài đặt nhiều lần bạn muốn
Làm thế nào về việc lưu trữ các id thời gian chờ trong một mảng toàn cục và xác định một phương thức để ủy quyền lời gọi hàm cho cửa sổ.
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
}
};
Bạn phải viết lại window.setTimeout
phương thức và lưu ID thời gian chờ của nó.
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();
}
}
Đặt mã dưới đây trước bất kỳ tập lệnh nào khác và nó sẽ tạo ra một hàm bao bọc cho bản gốc setTimeout
& clearTimeout
.
Một clearTimeouts
phương thức mới sẽ được thêm vào window
Đối tượng, cho phép xóa tất cả thời gian chờ (đang chờ xử lý) ( liên kết Gist ).
Các câu trả lời khác thiếu hỗ trợ đầy đủ cho các lập luận khả thi
setTimeout
có thể nhận được.
// 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);
Để hoàn thiện, tôi muốn đăng một giải pháp chung bao gồm cả setTimeout
và setInterval
.
Có vẻ như các trình duyệt có thể sử dụng cùng một nhóm ID cho cả hai, nhưng từ một số câu trả lời cho clearTimeout và clearInterval có giống nhau không? , không rõ liệu có an toàn khi dựa vào clearTimeout
và clearInterval
thực hiện cùng một chức năng hay chỉ hoạt động trên các loại hẹn giờ tương ứng của chúng.
Do đó, khi mục tiêu là loại bỏ tất cả thời gian chờ và khoảng thời gian, đây là một triển khai có thể phòng thủ hơn một chút trên các triển khai khi không thể kiểm tra tất cả chúng:
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(){}
}
Bạn có thể sử dụng nó để xóa tất cả các bộ hẹn giờ trong cửa sổ hiện tại:
clearAll(window);
Hoặc bạn có thể sử dụng nó để xóa tất cả các bộ hẹn giờ trong iframe
:
clearAll(document.querySelector("iframe").contentWindow);
Tôi sử dụng Vue với 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
}
}
Sử dụng thời gian chờ chung mà tất cả các chức năng khác của bạn bắt nguồn từ thời gian. Điều này sẽ làm cho mọi thứ chạy nhanh hơn và dễ quản lý hơn, mặc dù nó sẽ thêm một số trừu tượng vào mã của bạn.
set_timeout
hàm toàn cục? Bạn có thể đưa ra một mã ví dụ?
Chúng tôi vừa xuất bản một gói giải quyết vấn đề chính xác này.
npm install time-events-manager
Cùng với đó, bạn có thể xem tất cả thời gian chờ và khoảng thời gian qua timeoutCollection
& intervalCollection
đối tượng. Ngoài ra còn có một removeAll
chức năng xóa tất cả thời gian chờ / khoảng thời gian khỏi bộ sưu tập và trình duyệt.