`
blueyanghualong
  • 浏览: 227807 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

setTimeout与setInterval在不同浏览器下的差异

阅读更多
setTimeout与setInterval是window对象的两个非常神奇方法,用于实现定时或延时调用一个函数或一段代码。
(新手可能认为setTimeout与setInterval是javascript函数,这是错误的。新手容易将javascript对象函数与DOM对象方法混淆。)

先来一段代码,大家猜猜在各种浏览器下的结果会是怎么样的呢?
function f(){
    var s = 'arguments.length:'+arguments.length+'; ';
    for(var i=0,n=arguments.length;i< n;i++){
        s += ' ['+i+']:'+arguments[i]+'; ';
    }
    alert(s);
}
setTimeout(f,500,"javascript","AAA")

我这里要探讨的,不是什么时候该用哪一个,而是探讨这两个方法在各浏览器中的差异。

原先我一直没觉得这两个方法会有什么乌龙,一个偶然的机会让我得知了,现在整理一下写出来和大家分享。

因为setTimeout与setInterval的参数和用法是一样的,只是功能不同,所以,为了省事,我下面只以setTimeout为例进行说明以及举例。

setTimeout被最经常用到的形式大概是如下2种样子的:

    iTimerID = setTimeout(strJsCode, 50)   //strJsCode为一个包含 js代码的字符串
    iTimerID = setTimeout(objFunction, 50) //objFunction为一个函数对象

第一种调用方式是传包含js代码的字符串,这种方式的好处是简洁,但坏处是运行效率差,而且不利于语法解析,有潜在风险,更重要的是,处理比较复杂的内容比较费劲,这一点和eval的弊端是一致的。
所以,我们认为,通常应当采用第二种方式调用为好。(后面我的例子均采用第2种调用方式)


现在来揭晓开头那一段代码在各种浏览器下的结果:
    IE(6,7,8)是: arguments.length:0;
    Opera(6,7,8)是: arguments.length:2;  [0]:javascript;  [1]:AAA;
    Firefox(3.0)是: arguments.length:3;  [0]:javascript;  [1]:AAA;  [2]:-15;
竟然有这么大的差别,还真是“你唱你的曲,我哼我的调”!
Firefox(3.0)下,得出的最后一个数字是不特定的,有时候是0,有时候是一个负数,这问题后面再说。


(一)IE系列中的setTimeout

首先,我们看看微软出的DHTML参考手册中是如何说的:

setTimeout Method
    Evaluates an expression after a specified number of milliseconds has elapsed.

Syntax
    iTimerID = window.setTimeout(vCode, iMilliSeconds [, sLanguage])

Parameters
    vCode               Required. Variant that specifies the function pointer or string that indicates
                                    the code to be executed when the specified interval has elapsed.
    iMilliSeconds     Required. Integer that specifies the number of milliseconds.
    sLanguage       Optional. String that specifies one of the following values:
                                  JScript Language is JScript.
                                  VBScript Language is VBScript.
                                  JavaScript Language is JavaScript.

MSDN上关于setTimeout的说明:
        http://msdn.microsoft.com/en-us/library/ms536753(VS.85).aspx

也就是说,setTimeout接收3个参数,第3个参数表示脚本语言的类型,如果你再传入更多的参数,是无意义的。
因此,在IE中,以下两种都是对的。
        setTimeout('alert(1)', 50);

        setTimeout('msgbox "终止、重试、忽略,您看着办吧。", vbAbortRetryIgnore + vbDefaultButton2, "告诉您"', 50, 'VBScript');


(二)Mozilla系列中的setTimeout

我们看看Mozilla官方网站上 Gecko DOM Reference 手册中是如何说的:
window.setTimeout
    Summary
        Executes a code snippet or a function after specified delay.

    Syntax
        var timeoutID = window.setTimeout(func, delay, [param1, param2, ...]);
        var timeoutID = window.setTimeout(code, delay);

前两个参数都一样,没差别,从第三个参数就不同了。
因为目前只有IE浏览器支持多种语言的脚本,其它浏览器只支持js脚本所以不需要传语言类型的参数。
Mozilla把传给setTimeout的第3个以及更后面的更多参数依次的传给前面的func做为参数。
Firefox, Opera, Safari, Chrome等等也都是如此。

但是注意到,Mozilla上说了他家的setTimeout有一个叫做"Lateness" argument的BUG.
        "Lateness" argument
                Functions invoked by setTimeout are passed an extra "lateness" argument in Mozilla,
                i.e., the lateness of the timeout in milliseconds. (See bug 10637 and bug 394769.)
这就是开头那个例子中,Firefox(3.0)下有一个乌龙数字的根源。

Mozilla上关于setTimeout的说明:
        https://developer.mozilla.org/en/DOM/window.setTimeout

(三)其它浏览器系列(Opera, Safari, Chrome)中的setTimeout
    和Mozilla系列中的基本一样,但是没有Mozilla系列中的多一个参数的BUG.


武林外传:使用setTimeout的小技巧

    (1)IE中给setTimeout中的调用函数传参数
        上面的分析可知,IE是不支持在setTimeout中给被调用的函数传参数的,为了浏览器世界的和谐,我们可以把函数调用参数包裹进新的匿名函数中。示例:
            function f(a){
                alert(a);
            }
            // setTimeout(f,50,'hello'); //用于非IE
            setTimeout(function(){f('hello')},50); //通用
            var str='hello';
            setTimeout(function(){f(str)},50); //通用

    (2)this问题
        setTimeout调用的函数被执行时的上下文是全局,而不再是调用setTimeout方法时的上下文。所以,setTimeout的第一个参数的函数被执行时其this是指向window的,如果需要保留调用setTimeout方法时的this,就需要把当时的this传进去。示例:
            function Person(name){
                this.name=name;
                var f=function(){alert('My name is '+this.name)};

                // setTimeout(f,50); //错误

                var THIS=this;
                setTimeout(function(){f.apply(THIS)},50); //正确,通用
                setTimeout(function(){f.call(THIS)},50); //正确,通用
            }
            new Person('Jack');

要说的就这些了。
发帖子不是脑力活,其实是体力活,组织文字,写例子,排版,这些没技术含量的事情是最累人最耗时间的。
分享到:
评论

相关推荐

    给你一个jingqsdfgnvsdljk

    给你一个jingqsdfgnvsdljk

    MPSK调制解调MATLAB仿真源代码

    MPSK调制解调MATLAB仿真源代码,包括调制的实现、解调的实现、运行结果等

    一个基于Java SE的跳跃忍者游戏.zip

    一个基于Java SE的跳跃忍者游戏.zip开发

    更新城市蔓延指数数据集(1990-2023年).xlsx

    详细介绍及样例数据:https://blog.csdn.net/li514006030/article/details/144034989

    Ripro9.0免扩展二开版WordPress博客主题Ripro全解密无后门

    RiPro9.0免扩展二开版,RiPro主题全解密无后门,这次分享的源码包内的东西不少 不仅含有RiPro主题、子主题,还有几款插件,都是非常实用的东西!下面我将逐一介绍一下。 1、ripro主题:本套ripro主题说的版本是ripro9.0,测试时看了下 应该是使用ripro8.9二开出来的9.0版本, 完全解密修正版,无后门更放心!免扩展、虚拟主机就能用!且修正了原版的多处BUG,更好用! 3、Wordpress插件:插件有DX-Watermark、图片自动加水印插件、Wordpress轻水印插件、WPCopyRights网站防复制插件和riprod插件,共四款。 测试报告:本次分享的源码包内的东西,测试了的有ripro9.0主题和源码包里附带的4款插件 在测试过程中无论是ripro主题还是自带的插件都未发现问题,均正常运行! 至于两款RiPro子主题我就没继续体验了,至于它们兼不兼容9.0版的ripro大家下载后再自己尝试吧 子主题属于赠品,本站未测试所以不保证是否能用。 另外,大家需要知道的是,测试源码始终只是处于测试的程度,并不是真正的运营使用 所以

    逆地理编码,Python实现本地化,无次数限制和访问限制

    逆地理编码,Python实现本地化,无次数限制和访问限制

    javascript删除重复字符.rar

    在 JavaScript 中删除字符串中的重复字符,可以通过使用集合(Set)来实现,因为集合是一种不允许重复值的数据结构。压缩包文件代码是一个简单的示例代码,展示了如何删除字符串中的重复字符,同时保持字符的顺序。

    好看的贺卡PSD源文件(14个).zip

    各种行业的贺卡PSD源文件(14个),酷炫好看的贺卡PSD,各种类型的贺卡PSD,总有一款合适你的,包含卡通人物主题婚礼感谢卡PSD模板,卡通新婚恋人婚庆主题感谢卡设计,圣诞快乐PSD贺卡设计,圣诞节黑金贺卡样机设计,恭喜新年贺卡PSD素材,恭贺新春PSD广告海报设计,教师节感恩贺卡psd模板,教师节精美贺卡psd模板,派对活动感谢卡A5模板,浪漫情人节贺卡设计PSD,清新艺术风贺卡模板设计,秋季元素装饰感谢卡ps素材,粉色卡通花卉感谢卡设计素材,读取目录下所有文件夹和文件名称.bat,香水主题感谢卡ps素材等等素材,可以直接PS上使用,改为自己的模板。

    基于C++ SFML图形库实现的的贪吃蛇小游戏课程设计

    【作品名称】:基于C++ SFML图形库实现的的贪吃蛇小游戏【课程设计】 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【项目介绍】: 编译环境的说明 Windows 11 专业版 GCC 11.2.0 MinGW-w64 9.0.0 (linked with msvcrt) GNU Make 4.3 SFML 2.5.1 全部 static 编译 特点 相比原版和大部分走直线的贪吃蛇,界面直白简单,动画丝滑流畅,操作易上手 操作 点击或长按任意位置,变化蛇的方向 按w/a/s/d或者上/下/左/右键转向 蛇到边界的时候会从对称一边出来 按住空格可以加速 【资源声明】:本资源作为“参考资料”而不是“定制需求”,代码只能作为参考,不能完全复制照搬。需要有一定的基础看懂代码,自行调试代码并解决报错,能自行添加功能修改代码。

    【创新未发表】基于北方苍鹰优化算法NGO-Kmean-Transformer-BiLSTM实现负荷预测附Matlab代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手

    bpi flash读ID程序

    bpi flash读ID程序

    基于Android+Java的连连看小游戏,图片资源是用的别人的.zip

    基于Android+Java的连连看小游戏,图片资源是用的别人的.zip算法

    所有国家的经纬度边界数据

    所有国家的经纬度边界数据

    基于hyperledger fabric区块链的工作流审批应用全部资料+详细文档.zip

    【资源说明】 基于hyperledger fabric区块链的工作流审批应用全部资料+详细文档.zip 【备注】 1、该项目是个人高分项目源码,已获导师指导认可通过,答辩评审分达到95分 2、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 3、本项目适合计算机相关专业(人工智能、通信工程、自动化、电子信息、物联网等)的在校学生、老师或者企业员工下载使用,也可作为毕业设计、课程设计、作业、项目初期立项演示等,当然也适合小白学习进阶。 4、如果基础还行,可以在此代码基础上进行修改,以实现其他功能,也可直接用于毕设、课设、作业等。 欢迎下载,沟通交流,互相学习,共同进步!

    基于区块链的网约车平台联盟链全部资料+详细文档.zip

    【资源说明】 基于区块链的网约车平台联盟链全部资料+详细文档.zip 【备注】 1、该项目是个人高分项目源码,已获导师指导认可通过,答辩评审分达到95分 2、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 3、本项目适合计算机相关专业(人工智能、通信工程、自动化、电子信息、物联网等)的在校学生、老师或者企业员工下载使用,也可作为毕业设计、课程设计、作业、项目初期立项演示等,当然也适合小白学习进阶。 4、如果基础还行,可以在此代码基础上进行修改,以实现其他功能,也可直接用于毕设、课设、作业等。 欢迎下载,沟通交流,互相学习,共同进步!

    java毕设项目之基于springboot+vue的大学生创业项目的信息管理系统(源码+说明文档+mysql).zip

    环境说明:开发语言:Java 框架:springboot JDK版本:JDK1.8 服务器:tomcat7 数据库:mysql 5.7 数据库工具:Navicat 开发软件:eclipse/myeclipse/idea Maven包:Maven 浏览器:谷歌浏览器。 项目均可完美运行

    GB材料数据库(!请注意鉴别其中的材料参数并不是完全正确!)

    - 数据库来源于学长在网上查找的资源。 - 已经发现其中的材料参数并不是完全正确,如Q235的屈服强度应该是234MPa,但是材质数据库中的参数并不是。

    完整数据-30米空间分辨率中国年度耕地栅格数据集(到2021)

    到在研究期间至少有419, 342平方公里(17.57%)的耕地至少发生了一次弃耕。一致而高分辨率的CACD数据集可以被用于各种研究应用中,以促进可持续农业利用和粮食生产进展。 数据容量:21.25GB 数据时间:1986-2021 数据格式:tif

Global site tag (gtag.js) - Google Analytics