IE下script标签的readyState属性

在做加载器时遇到一个常见问题,如何判定一个脚本已经执行完毕。

  • “uninitialized” – 原始状态
  • “loading” – 下载数据中
  • “loaded” – 下载完成
  • “interactive” – 还未执行完毕
  • “complete” – 脚本执行完毕.

网上流行的答案是这个,我怎么觉得其实这是抄自XMLHttpRequest的readyState呢?!恰逢这两个都有这属性。

我们亲自做一个实验:

<!DOCTYPE html>
<html>
    <head>
        <title>node.readyState</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width">
        <script>
            var node = document.createElement("script")
            node.onreadystatechange = function() {
                var state = node.readyState
                setTimeout(function() {
                    var div = document.createElement("div")
                    document.body.appendChild(div)
                    div.innerHTML = state
                }, 300)

            }
            var head = document.getElementsByTagName("head")[0]
            head.appendChild(node)
            node.src = "avalon.js"

        </script>
    </head>
    <body>
        <div>node.readyState</div>
    </body>
</html>
完整的控件教程
IE11 空白,说明完全与标准一致了
IE10 loading loaded
IE9 loading loaded
IE8 complete loaded
IE7 complete loaded 但有一定机率,只出现complete或loaded
IE6 complete loaded 但有一定机率,只出现complete或loaded

换言之,IE67是个非常悲催的问题。另外,opera9-10也支持readyState,根据老外的描述,它竟然两次都是loaded!

因此我们需要根据浏览器的情况采用不同的策略。

首先是使用何种回调,如果是支持onload事件,那么就直接用onload 就没有这么多麻烦事。最简单的策略是这样判定:

        var node = DOC.createElement("script")
        var supportLoad = "onload" in node
        var onEvent = supportLoad ? "onload" : "onreadystatechange"
        node[onEvent] = callback

判定完成时机, 我们不使用网上的/complete|loaded|undefined/.test(node.readyState),这会同时掉进opera与IE67的坑中。对于使用onload事件进行监听的,不再判定node.readyState,IE(其实也就是IE6-8),需要使用一个定时器。当第一次进行onreadystatechange回调时,timeID为空, 并且readyState为complete或loaded时,我们设置它在300ms后再执行自身。然后如果浏览器还执行此回调时, 它就进入第二个分支,清掉定时器,执行用户代码。万一,浏览器只执行一次onreadystatechange回调,那也没关系,让定时器100~300ms后执行用户代码

最后贴出全部代码:

        //通过script节点加载目标模块
        var node = DOC.createElement("script")
        var timeID
        var supportLoad = "onload" in node
        var onEvent = supportLoad ? "onload" : "onreadystatechange"
        node[onEvent] = function onLoad() {
            if (!supportLoad && !timeID && /complete|loaded/.test(node.readyState)) {
                timeID = setTimeout(onLoad)
                return
            }
            if (supportLoad || timeID) {
                clearTimeout(timeID)
                //你的代码
            }
        }

        head.insertBefore(node, head.firstChild) //chrome下第二个参数不能为null
        node.src = url //插入到head的第一个节点前,防止IE6下head标签没闭合前使用appendChild抛错

大家也可以到这里看一下它的实际应用,如果大家都是使用AMD规范定义JS文件,那么我在旧式IE下连onerror也模拟出来了。

时间: 2024-08-28 12:46:08

IE下script标签的readyState属性的相关文章

&lt;script&gt;标签里面的属性详解

1. <script>标签里面,4.01时候定义了6个属性,有:defer async charset language src  type 2. defer属性:脚本立即下载但延迟到文档被解释和执行之后才执行,在HTML5里面虽然规定了脚本要按照它们出现的顺序来执行,但实际上,延迟脚本不一定会按照顺序执行,所以最好只出现一个延迟脚本.现在大多数支持HTML5的浏览器会忽略这个属性,像正常一样处理延迟脚步,最好还是把延迟脚步放在</body>前面. 3.async属性: 表示立即下

script标签的src属性

src属性指定外部文件路径,浏览器根据src属性值请求外部文件然后将外部文件的内容插入script标签之间,结果会覆盖原本script标签之间的内容,类似于document.write()会覆盖原本的dom一样.导致在编辑时写入的js代码不会被执行. 文件并非必须是js文件,任意类型的文本文件都可以,比如html,css,xml,txt.要求是这些文件里面的内容是js代码即可. 文件 "5.txt" 内容:console.log("5.txt"); <!--

如何将 JavaScript 代码添加到网页中,以及 &lt;script&gt; 标签的属性

Hello, world! 本教程的这一部分内容是关于 JavaScript 语言本身的. 但是,我们需要一个工作环境来运行我们的脚本,由于本教程是在线的,所以浏览器是一个不错的选择.我们会尽可能少地使用浏览器特定的命令(比如 alert),所以如果你打算专注于另一个环境(比如 Node.js),你就不必多花时间来关心这些特定指令了.我们将在本教程的下一部分中专注于浏览器中的 JavaScript. 首先,让我们看看如何将脚本添加到网页上.对于服务器端环境(如 Node.js),你只需要使用诸如

JavaScript之&lt;script&gt;标签简介

向html页面中插入JavaScrpt的主要方法,就是使用<script>元素,下面是Html 4.01为<script>定义的6个属性. 1.async:可选表示应该立即下载脚本,但是不妨碍页面中的其他操作,比如下载比如下载其他资源或等待加载其他脚本.这个属性只对外部脚本有效 2.charset:可选.表示脚本通过src属性指定的代码的字符集.大多数浏览器会忽略它的值,所以这个属性也很少用. 3.defer:可选.表示脚本可以延迟到文档完全被解析和显示之后在执行.只对外部脚本有效

移除script标签引起的兼容性问题

一.应用场景: 有时候我们需要动态创建script标签实现脚本的按需加载,我们会为script标签绑定onload或者onreadystatechange事件,用于检测动态脚本是否加载并执行完毕,在事件处理程序中引用动态脚本创建的变量. 二.问题描述: 如果我们动态创建script标签并绑定事件处理程序后,立即移除script标签,那么事件处理程序是否会执行?如果能执行,那么能否正常引用动态脚本创建的变量? 三.看如下程序: function inviteFriends() { var self

js中的script标签

在页面中用script标签引入javascript文件(<script type="text/javascript" src="js文件地址"></script>),浏览器在渲染页面的时候,当读取到script元素时,浏览器不会以HTML或XHTML的方式处理其内容,浏览器会通知浏览器的脚本引擎来接管script元素中的内容.   script元素的type属性定义脚本类型,type类型有: 1.text/ecmascript(表示以ECMA

获取标签的src属性兼容性

获取节点如script标签的src属性时,针对非IE6,IE7可以直接使用src属性,但在IE6-7中存在问题,可以借助getAttribute方法 getAttribute(attr,iflag) iflag 取值: 0: 属性不区分大小写,但是返回一个被修改的值 1:区分大小写,必须严格和属性名匹配才能查找到 2:返回一个字符串,但是针对事件属性不适用 4:返回一个扩展的url,完整的url值,只针对url属性有效 官方文档:https://msdn.microsoft.com/en-us/

JS 之 script标签

1.script标签 1.js代码的解析(包括下载js文件)会阻塞页面加载 2.当js文件放在头部,页面必须等所有js代码都被下载,解析和执行完成后才开始呈现页面内容(遇到body标签才呈现),对于那些需要很多js文件的页面来说,会有很大的延迟,浏览器页面空白时间,              所以尽量把全部js文件引用放在body标签内的最底部,先呈现内容,用户体验更好2.defer延迟脚本 script标签加上defer属性,浏览器会异步地下载该文件,不会影响后续dom的渲染,如果有多个def

1关于script标签属性,注意点,浏览器文档模式

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head>    <title></title></h