setTimeout问题餐厅

1971人阅读
javascript(138)
写定时器分两种写法,setInterval和setTimeout。
先来说setInterval:
setInterval(code,millisec[,&lang&])
setInterval() 方法可按照指定的周期(以毫秒计)来调用函数或计算表达式。
setInterval() 方法会不停地调用函数,直到 clearInterval() 被调用或窗口被关闭。
由 setInterval() 返回的 ID 值可用作 clearInterval() 方法的参数。
再来说说setTimeout:
setTimeout(code,millisec)
setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式。
setTimeout() 只执行 code 一次。如果要多次调用,请使用 setInterval() 或者让 code 自身再次调用 setTimeout()。
通过分析可以得出一个结论,如果要做一个定时器的应用,setInterval可以使用匿名函数实现,setTimeout却不可以。例如:
如果使用setTimeout实现定时器,则需要首先定义一个函数,之后使用 setTimeout() 调用该函数,最后在该函数中再次调用 setTimeout()。
如果按照这个逻辑代码应该是这样的:
运行后却发现有错误:Uncaught ReferenceError: redraw is not defined。
如果运行代码没在 window.onload = function(){}环境下,即把 window.onload = function(){} 方法去除:
这样错误就消失了,为什么呢?如果换成setInterval调用呢?
发现会报同样的错误:Uncaught ReferenceError: redraw is not defined。
说到这里也就明了了,因为无论是setInterval还是setTimeout都只能调用全局函数,即挂在window下的函数。
那么解决方案是什么呢?
既然发现了问题是无论setInterval还是setTimeout都只能调用全局函数,
那么只要把redraw函数放到window.onload方法外面定义就可以解决这个棘手问题。还拿setTimeout为例:
注意一:调用函数时如果函数名外加了引号,则()也要写上,如setTimeout('redraw()',30),不然虽然不会报错,但程序也不会执行。
可以不加引号,只写函数名,如setTimeout(redraw,30),或则函数名(),如setTimeout(redraw(),30)。
注意二:调用函数传递参数时,尽可能使用不带引号的方式传递,因为在加引号的情况下传递参数会出现各种问题,这里就不一一介绍了。
还没完,运行了代码发现又有错误:Uncaught RangeError: Maximum call stack size exceeded.
翻译过来就是因为递归次数太多导致内存被耗费太多。真是坑爹啊。
最后在网上找的一个方法_setTimeout替代setTimeout方法,具体原理就不解释了,其实我也不太懂。?
完整无误的JS代码:
具体效果请运行下面完整代码:
&!DOCTYPE html&
&meta http_equiv=&Content_Type& content=&text/ charset=utf-8& /&
&title&canvas&/title&
&style type=&text/css&&
#cv { background-color:#000; margin-left:420 margin-top:100 }
&canvas id=&cv& width=&400& height=&400&&
&p&该浏览器不支持canvas。&/p&
&/canvas& &!-- canvas画布默认宽300px,高150px,背景颜色为白色 --&
&script type=&text/javascript&&
window.onload = function(){
var oC = document.getElementById('cv'),
oGC = oC.getContext('2d'),
width = 100,
height = 100,
step:step,
width:width,
height:height
oGC.fillStyle = 'rgba(0,255,255,1)';
oGC.fillRect(0,0,width,height);
_setTimeout(redraw,30,param);
var step = 0;
function redraw(param){
var oC = param.oC,
oGC = param.oGC,
width = param.width,
height = param.
oGC.clearRect(0,0,oC.width,oC.height);
oGC.fillRect(step,step,width,height);
_setTimeout(redraw,30,param);
function _setTimeout(callback,timeout,param){
var args = Array.prototype.slice.call(arguments,2);
var _cb = function(){
callback.apply(null,args);
setTimeout(_cb,timeout);
源引:/separticle.php?artid=202
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:400704次
积分:3709
积分:3709
排名:第8986名
转载:433篇
(3)(25)(26)(50)(11)(1)(7)(3)(22)(42)(27)(64)(6)(3)(11)(62)(32)(1)(1)(18)(23)
(window.slotbydup = window.slotbydup || []).push({
id: '4740887',
container: s,
size: '250,250',
display: 'inlay-fix'js中setTimeout的问题 - 流水账 - ITeye博客
博客分类:
&&& 昨天在公司里写了个程序,发现js中setTimeout这块代码出错,于是写了一小段代码专门来测试,便遇到一个不解的问题。看代码。
&script type="text/javascript" src="script/jquery-1.2.6.js"&&/script&
&script type="text/javascript"&
$(document).ready(function(){
var age = 1;
function AddIt(){
age = $("#yourAge").val();
alert(age);
$("#yourAge").val(age);
setTimeout("AddIt()",1000);
//$("#yourAge").blur(function(){
&input type="text" id="yourAge" value="4" &
&& 文本框内的数字每隔一秒会自动加1.
&& 可是如果将代码放到$().ready(function(){})中,就会出错,或者将注释去掉,由离开焦点来触发函数,同样会出错。google了一下也没有得到结果。希望js高手能解答。
论坛回复 /
(4 / 3189)
orcl_zhang
浏览: 129523 次
来自: 杭州
回去倒立去,哈哈。
Ruby MetaProgramming is all abo ...
yiqi1943 写道LZ现在上学还是工作呢工作好多年了。不过 ...
LZ现在上学还是工作呢
query cache
就是一个简单的hash
key就是sq ...问题对人有帮助,内容完整,我也想知道答案
问题没有实际价值,缺少关键内容,没有改进余地
for (var i = 0; i &= 3; i++) {
setTimeout(function
console.log(i);
for (var i = 0; i &= 3; i++) {
setTimeout(function
console.log(a);
为什么结果是:01234 ,这里打印了4次延迟的时间为0,为何先执行下面的for循环呢,为何上面的for循环打印的最终的i,下面的for循环是逐个打印呢?
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
1.setTimeout绑定的回调函数只是往Javascript的事件循环机制中注册了一个定时器,这个定时器只可能在当前时间循环的下一次事件循环中才有可能被执行(需要检查时间是否符合设置的时间点)2.
console.log(a);
是一个立即执行函数,在你setTimeout函数执行调用时就被执行了,而不是等到定时器到点后被执行3.setTimeout(fn,0)并不是立即执行的语义,只是说在下一次时间循环到达时可以马上执行4.打印4次4的问题
for (var i = 0; i &= 3; i++) {
setTimeout(function
console.log(i);
for (i = 0; i &= 3; i++) {
setTimeout(function
console.log(i);
输出4次4是因为javacript没有块作用域,只有函数作用域,一个函数在定义时其中俄变量的作用域就确定;函数中变量i的指向的a处声明的变量,在for循环结束后i的值就是4并且你定义了4个同样的定时器
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
异步 异步 异步重要的事儿说3次第二个一定后打印 结果4444
为什么第二个先打印 很简单
console.log(a);
你直接执行了回调函数 就这么简单 由于 异步 所以 第一个循环 结果会后出来
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
首先你要理解延迟时间0的问题,其次呢,你还需要理解函数执行的问题,再次,你还要理解闭包的问题;
第一,为什么先执行了下面的for循环?
因为在你第二个for循环中的setTimeout里面不只是一个简单的匿名函数,而是你定义了一个匿名函数后就立马执行了(因为你函数定义后使用了(i)进行调用并把i当做参数传到函数里),此处立马执行的意思是代码执行到这里,这个函数就被调用了...所以就开始打印0,1,2,3
而setTimeout延迟0并不代表你使用了setTimeout之后0秒就立即执行了,如果0秒立即执行,那么会先执行setTimeout设置的延迟0所应该调用的函数然后才继续执行下面的代码,而此处0是指设定一个任务,当现有的任务执行完了之后延迟0(若有设置时间则延迟相应的时间)开始执行,所以此处会先执行完现有的代码之后才会执行所谓的延迟0的那个该调用的函数
这样谁先谁后就很明了了
第二,为什么上面的for循环打印的是最终的i?
结合第一点,那些你在第一个for循环里逐次设定的延迟0的回调函数都是在这里所有代码都执行完了之后才执行的,那么那时候i这个变量经过了第二个for循环的遍历之后已经变成了4,因为这里的所有的变量i都是使用的同一个,所以这时候才执行的function里所取到的i已经都是4了
同步到新浪微博
分享到微博?
你好!看起来你挺喜欢这个内容,但是你还没有注册帐号。 当你创建了帐号,我们能准确地追踪你关注的问题,在有新答案或内容的时候收到网页和邮件通知。还能直接向作者咨询更多细节。如果上面的内容有帮助,记得点赞 (????)? 表示感谢。
明天提醒我
关闭理由:
删除理由:
忽略理由:
推广(招聘、广告、SEO 等)方面的内容
与已有问题重复(请编辑该提问指向已有相同问题)
答非所问,不符合答题要求
宜作评论而非答案
带有人身攻击、辱骂、仇恨等违反条款的内容
无法获得确切结果的问题
非开发直接相关的问题
非技术提问的讨论型问题
其他原因(请补充说明)
我要该,理由是:1378人阅读
Web开发(36)
今天检查自己用JQuery+AJAX+PHP做的网站后台登录检测,发现登陆成功后执行页面跳转函数这段JavaScript(JS)代码特效在IE和谷歌浏览器Chrome下都可以很好地执行,兼容性还不错。结果到了火狐(FireFox)浏览器下setTimeout这个JS内置函数不执行了,无效了,也没报错!打开FireBUG指望它能检测出JS的错误,结果没用...Javascript(JS)脚本代码在各浏览器下的兼容是一个很头疼的问题,经过一番调试和搜索,终于解决了setTimeout这个JS代码在火狐下失效不兼容不能运行和执行的错误。目前这个setTimeout可以很好地兼容IE6,7,8,9以及谷歌浏览器Chrome,火狐浏览器FireFox,苹果浏览器Safari,Opera。
setTimeout是一个很不错的函数,网站页面前端工程师经常将其用于几秒后执行的动作。setTimeout这个JS内置函数其用法也很简单,下面是setTimeout()的函数说明以及用法详解和实例、示例代码:
setTimeout()的作用是指定在多少毫秒后执行一个JS函数或者表达式代码
setTimeout的用法、语法、参数:setTimeout(code,millisec)
setTimeout参数说明:
code是必需参数。要调用的函数后要执行的 JavaScript 代码串。
millisec是必需参数。在执行代码前需等待的毫秒数。毫秒和秒之间的换算是:1000毫秒=1秒
setTimeout实例代码(1秒后页面跳转到指定的URL):
&script language=&javascript&&
function go(){//定义函数
window.location=&main.html&;//页面跳转
window.setTimeout(&go()&,1000);//1秒后执行函数go
但是以上JS代码是无法兼容火狐的,这主要是因为IE和火狐的浏览器引擎是不同的。让这段页面跳转JS代码兼容IE、火狐、SAFARI、OPERA:&script language=&javascript&&
function go(){//定义函数
window.location=&main.html&;//页面跳转
window.setTimeout(function(){go()},1000);//1秒后执行函数go
但是如果在提交表单的时候:
&input id=&submit& class=&submit& type=&button& name=&submit& value=&查寻& &
type是不能用submit的,纠结。。。。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:109270次
积分:3062
积分:3062
排名:第11729名
原创:206篇
转载:10篇
(1)(1)(2)(1)(3)(4)(1)(1)(1)(1)(1)(2)(2)(7)(1)(3)(5)(3)(2)(12)(7)(1)(7)(11)(11)(6)(7)(23)(16)(5)(31)(37)
(window.slotbydup = window.slotbydup || []).push({
id: '4740887',
container: s,
size: '250,250',
display: 'inlay-fix'}

我要回帖

更多关于 问题餐厅 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信