【javascript基础】【setTimeout setInterval】 之 setTimeout基本概念及浏览器兼容性
2012-11-13 16:56
926 查看
一、定义:
在指定的延迟时间之后调用一个函数或者执行一个代码片段.
二、语法:
var timeoutID = window.setTimeout(func, delay, [param1, param2, ...]);
var timeoutID = window.setTimeout(code, delay);
说明:
需要注意的是,IE不支持第一种语法中向延迟函数传递额外参数的功能.如果你想要在IE中达到同样的功能,你必须使用一种兼容代码 (查看callback arguments 一段).
备注: 在Gecko 13之前 (Firefox 13.0 / Thunderbird 13.0 / SeaMonkey 2.10), Gecko会给延迟函数传递一个额外的参数,该参数表明了此次延迟操作实际延迟的毫秒数.现在,这个非标准的参数已经不存在了.
DEMO:
function generateOutput(aConcise) {
if(aConcise) {
parent.generateConciseOutput();
} else {
parent.generateOutput();
}
}
window.setTimeout(generateOutput, 1000, true); // IE中不会把"true"传给generateOutput
1
2
3
4
// 使用匿名函数来提供兼容性
setTimeout(function() {
generateOutput(true);
}, 1000); // 兼容所有浏览器
1
window.setTimeout("window.parent.generateOutput(true)", 1000); // 不推荐的用法
三、回调函数
如果你需要向你的回调函数内传递一个参数, 而且还需要兼容IE, 由于IE不支持传递额外的参数 (
/*\
|*|
|*| IE-specific polyfill which enables the passage of arbitrary arguments to the
|*| callback functions of javascript timers (HTML5 standard syntax).
|*|
|*| https://developer.mozilla.org/en-US/docs/DOM/window.setInterval |*|
|*| Syntax:
|*| var timeoutID = window.setTimeout(func, delay, [param1, param2, ...]);
|*| var timeoutID = window.setTimeout(code, delay);
|*| var intervalID = window.setInterval(func, delay[, param1, param2, ...]);
|*| var intervalID = window.setInterval(code, delay);
|*|
\*/
if (document.all && !window.setTimeout.isPolyfill) {
var __nativeST__ = window.setTimeout;
window.setTimeout = function (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */) {
var aArgs = Array.prototype.slice.call(arguments, 2);
return __nativeST__(vCallback instanceof Function ? function () {
vCallback.apply(null, aArgs);
} : vCallback, nDelay);
};
window.setTimeout.isPolyfill = true;
}
if (document.all && !window.setInterval.isPolyfill) {
var __nativeSI__ = window.setInterval;
window.setInterval = function (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */) {
var aArgs = Array.prototype.slice.call(arguments, 2);
return __nativeSI__(vCallback instanceof Function ? function () {
vCallback.apply(null, aArgs);
} : vCallback, nDelay);
};
window.setInterval.isPolyfill = true;
}
另外一中方法是使用匿名函数来调用你的回调函数,但这中解决办法效率会低一些:
var intervalID = setTimeout(function() { myFunc("one", "two", "three"); }, 1000);
四、关于this指向问题
当你向
myArray = ["zero", "one", "two"];
myArray.myMethod = function (sProperty) {
alert(arguments.length > 0 ? this[sProperty] : this);
};
myArray.myMethod(); // prints "zero,one,two"
myArray.myMethod(1); // prints "one"
setTimeout(myArray.myMethod, 1000); // prints "[object Window]" after 1 second
setTimeout(myArray.myMethod, 1500, "1"); // prints "undefined" after 1,5 seconds
// let's try to pass the 'this' object
setTimeout.call(myArray, myArray.myMethod, 2000); // error: "NS_ERROR_XPC_BAD_OP_ON_WN_PROTO: Illegal operation on WrappedNative prototype object"
setTimeout.call(myArray, myArray.myMethod, 2500, 2); // same error 正如你所看到的一样,我们没有任何方法将
// Enable the passage of the 'this' object through the JavaScript timers
var __nativeST__ = window.setTimeout, __nativeSI__ = window.setInterval;
window.setTimeout = function (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */) {
var oThis = this, aArgs = Array.prototype.slice.call(arguments, 2);
return __nativeST__(vCallback instanceof Function ? function () {
vCallback.apply(oThis, aArgs);
} : vCallback, nDelay);
};
window.setInterval = function (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */) {
var oThis = this, aArgs = Array.prototype.slice.call(arguments, 2);
return __nativeSI__(vCallback instanceof Function ? function () {
vCallback.apply(oThis, aArgs);
} : vCallback, nDelay);
};
备注: 这两个替换也让IE支持了HTML标准的定时器函数.所以页能作为一polyfills. 查看 Callback arguments 一段. 参考文档:
https://developer.mozilla.org/zh-CN/docs/DOM/window.setTimeout
在指定的延迟时间之后调用一个函数或者执行一个代码片段.
二、语法:
var timeoutID = window.setTimeout(func, delay, [param1, param2, ...]);
var timeoutID = window.setTimeout(code, delay);
说明:
timeoutID是该延时操作的数字ID, 此ID随后可以用来作为window.clearTimeout方法的参数.
func是你想要在
delay毫秒之后执行的函数.
code在第二种语法,是指你想要在
delay毫秒之后执行的代码 (使用该语法是不推荐的, 不推荐的原因和eval()一样)
delay是延迟的毫秒数 (一秒等于1000毫秒),函数的调用会在该延迟之后发生.但是实际的延迟时间可能会稍长一点,查看下面的备注.
需要注意的是,IE不支持第一种语法中向延迟函数传递额外参数的功能.如果你想要在IE中达到同样的功能,你必须使用一种兼容代码 (查看callback arguments 一段).
备注: 在Gecko 13之前 (Firefox 13.0 / Thunderbird 13.0 / SeaMonkey 2.10), Gecko会给延迟函数传递一个额外的参数,该参数表明了此次延迟操作实际延迟的毫秒数.现在,这个非标准的参数已经不存在了.
DEMO:
function generateOutput(aConcise) {
if(aConcise) {
parent.generateConciseOutput();
} else {
parent.generateOutput();
}
}
window.setTimeout(generateOutput, 1000, true); // IE中不会把"true"传给generateOutput
1
2
3
4
// 使用匿名函数来提供兼容性
setTimeout(function() {
generateOutput(true);
}, 1000); // 兼容所有浏览器
1
window.setTimeout("window.parent.generateOutput(true)", 1000); // 不推荐的用法
三、回调函数
如果你需要向你的回调函数内传递一个参数, 而且还需要兼容IE, 由于IE不支持传递额外的参数 (
setTimeout()或者
setInterval()都不可以) ,但你可以引入下面的兼容代码.该代码能让IE也支持符合HTML5标准的定时器函数.
/*\
|*|
|*| IE-specific polyfill which enables the passage of arbitrary arguments to the
|*| callback functions of javascript timers (HTML5 standard syntax).
|*|
|*| https://developer.mozilla.org/en-US/docs/DOM/window.setInterval |*|
|*| Syntax:
|*| var timeoutID = window.setTimeout(func, delay, [param1, param2, ...]);
|*| var timeoutID = window.setTimeout(code, delay);
|*| var intervalID = window.setInterval(func, delay[, param1, param2, ...]);
|*| var intervalID = window.setInterval(code, delay);
|*|
\*/
if (document.all && !window.setTimeout.isPolyfill) {
var __nativeST__ = window.setTimeout;
window.setTimeout = function (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */) {
var aArgs = Array.prototype.slice.call(arguments, 2);
return __nativeST__(vCallback instanceof Function ? function () {
vCallback.apply(null, aArgs);
} : vCallback, nDelay);
};
window.setTimeout.isPolyfill = true;
}
if (document.all && !window.setInterval.isPolyfill) {
var __nativeSI__ = window.setInterval;
window.setInterval = function (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */) {
var aArgs = Array.prototype.slice.call(arguments, 2);
return __nativeSI__(vCallback instanceof Function ? function () {
vCallback.apply(null, aArgs);
} : vCallback, nDelay);
};
window.setInterval.isPolyfill = true;
}
另外一中方法是使用匿名函数来调用你的回调函数,但这中解决办法效率会低一些:
var intervalID = setTimeout(function() { myFunc("one", "two", "three"); }, 1000);
四、关于this指向问题
当你向
setTimeout()(或者其他函数也行)传递一个函数时,该函数中的
this会指向一个错误的值.这个问题在JavaScript reference中进行了详细解释.
解释
由setTimeout()调用的代码运行在与所在函数完全分离的执行环境上. 这会导致,这些代码中包含的
this关键字会指向
window(
全局对象)对象,这和
所期望的this的值是不一样的.查看下面的例子:
myArray = ["zero", "one", "two"];
myArray.myMethod = function (sProperty) {
alert(arguments.length > 0 ? this[sProperty] : this);
};
myArray.myMethod(); // prints "zero,one,two"
myArray.myMethod(1); // prints "one"
setTimeout(myArray.myMethod, 1000); // prints "[object Window]" after 1 second
setTimeout(myArray.myMethod, 1500, "1"); // prints "undefined" after 1,5 seconds
// let's try to pass the 'this' object
setTimeout.call(myArray, myArray.myMethod, 2000); // error: "NS_ERROR_XPC_BAD_OP_ON_WN_PROTO: Illegal operation on WrappedNative prototype object"
setTimeout.call(myArray, myArray.myMethod, 2500, 2); // same error 正如你所看到的一样,我们没有任何方法将
this对象传递给回调函数.
解决方案
一个可用的解决 "this" 问题的方法是使用两个非原生的
setTimeout()和
setInterval()全局函数代替原生的.该非原生的函数通过使用
Function.prototype.call方法激活了正确的作用域.下面的代码显示了应该如何替换:
// Enable the passage of the 'this' object through the JavaScript timers
var __nativeST__ = window.setTimeout, __nativeSI__ = window.setInterval;
window.setTimeout = function (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */) {
var oThis = this, aArgs = Array.prototype.slice.call(arguments, 2);
return __nativeST__(vCallback instanceof Function ? function () {
vCallback.apply(oThis, aArgs);
} : vCallback, nDelay);
};
window.setInterval = function (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */) {
var oThis = this, aArgs = Array.prototype.slice.call(arguments, 2);
return __nativeSI__(vCallback instanceof Function ? function () {
vCallback.apply(oThis, aArgs);
} : vCallback, nDelay);
};
备注: 这两个替换也让IE支持了HTML标准的定时器函数.所以页能作为一polyfills. 查看 Callback arguments 一段. 参考文档:
https://developer.mozilla.org/zh-CN/docs/DOM/window.setTimeout
相关文章推荐
- 【javascript基础】【setTimeout setInterval】 之 How JavaScript Timers Work [译]
- 让JavaScript中计时器setTimeout/setInterval的回调方法支持参数传递
- Javascript(十二) setTimeOut & setInterval
- JavaScript Timers with setTimeout and setInterval
- JavaScript———从setTimeout与setInterval到AJAX异步
- JavaScript Timers with setTimeout and setInterval
- Javascript 调度: setTimeout and setInterval
- 带领大家学习javascript基础篇(一)之基本概念
- JavaScript———从setTimeout与setInterval到AJAX异步
- JavaScript的基本概念及程序设计基础
- 【javascript基础】1、基本概念
- JavaScript中从setTimeout与setInterval到AJAX异步
- javascript setTimeout setInterval使用详解
- 理解JavaScript 执行机制及异步回调(setTimeout/setInterval/Promise)
- JavaScript基础——基本概念:数据类型及其转换
- 【javascript基础】1、基本概念
- 在 Javascript 类中使用 setTimeout & 带参数的window.setTimeout(参数可为对象)
- javascript settimeout and setinterval
- javaScript知识点总结-----setTimeout setInterval 区别
- JavaScript基础笔记(一)基本概念