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也模拟出来了。
IE下script标签的readyState属性的更多相关文章
- [转]HTML5 script 标签的 crossorigin 属性到底有什么用?
HTML5 script 标签的 crossorigin 属性到底有什么用? 最近Bootstrap 4已经正式发布了,可能已经有爱尝鲜的小伙伴在 alpha 阶段就尝试过 BS4.不过今天要说的不是 ...
- 怎样理解script标签的defer属性和async属性
如果script标签是引用的外部js文件, 那就会有一个下载js文件这一过程, 为了不因为这个下载过程而阻塞页面解析与渲染, 我们需要一种机制来解决这一问题, 方法之一就是使用 defer和async ...
- html中script标签使用async属性和defer属性的区别
相同点: 首先async和defer只对header里的外连脚本script标签上起作用,如果script标签是放在header外或者是header里的内置脚本以及动态生成的script标签是不起作用 ...
- script标签不带属性与带async、defer的区别
<script> 当页面解析到script标签时,会停止解析并下载对应的脚本,并马上执行,执行完毕后再继续解析页面 <script async> async 在下载脚本的同时不 ...
- script标签的crossorigin属性
通常我们使用window.onerror来捕获js脚本的错误信息. 但是对于跨域调用的js脚本,onerror事件只会给出很少的报错信息:error: Script error. 这个简单的信息很明显 ...
- select标签下option标签里value属性有什么用以及和text的区别
转自:http://blog.csdn.net/summer_sy/article/details/54572398 1:value的用处 <select > <option val ...
- script标签属性sync和defer
<script src="a.js" defer></script> 加了defer属性script标签的页面,运行流程如下: 1.浏览器开始解析HTM ...
- 如何将 JavaScript 代码添加到网页中,以及 <script> 标签的属性
Hello, world! 本教程的这一部分内容是关于 JavaScript 语言本身的. 但是,我们需要一个工作环境来运行我们的脚本,由于本教程是在线的,所以浏览器是一个不错的选择.我们会尽可能少地 ...
- script标签crossorigin属性及同源策略和跨域方法
首先介绍(同源策略) 同源策略是浏览器最核心且基本的安全约定,要求协议.域名.端口都相同为同源,如果非同源时请求数据浏览器会在控制台抛出跨域异常错误,同源策略是浏览器的行为,即使客户端请求发送了,服务 ...
随机推荐
- C#检测鼠标移动消息
当C#窗口上有其它控件时,窗口本身检测不到消息.1.使用WndProc.MouseMove不行,比如 protected override void WndProc(ref Message m) { ...
- OpenCV中MAT中数据类型的设置(转)
前言 opencv中很多数据结构为了达到內存使用的最优化,通常都会用它最小上限的空间来分配变量,有的数据结构也会因为图像文件格式的关系而给予适当的变量,因此需要知道它们声明的空间大小来配置适当的变量. ...
- android ListView使用
1.DbOpenHelper package dbOpenHelper; import android.content.Context; import android.database.sqlite. ...
- 字典取KEY,占位符,延迟刷新
flash 监听事件者 与 事件发出者 比如说现在有A和B,A.addChild(B)A监听鼠标点击事件那么当点击B时,target是B,currentTarget是A也就是说,currentTarg ...
- luogu P4568 [JLOI2011]飞行路线
传送门 看到免费次数\(k\)最多只有10,可以考虑构建\(k+1\)层的分层图,即每一层正常连边,上下两层对应点连边权为0的单向边,最后对所有层里面的\(di_t\)取\(\max\)救星了 #in ...
- CTSC&APIO2018游记
Day-1 布吉岛干什么,好像只看了Splay Day0 再次布吉岛干什么,好像也只看了Splay 然后上了火车 wc没买方便面,只能吃40元的盒饭 半夜睡不着,那应该是我太菜了 Day1 九点下火车 ...
- transition,过渡效果
语法: transtion:property time change-speed delay. 人话就是:属性(property )在多少秒内(time )通过什么样的速度(change-speed) ...
- B - Finding Palindromes (字典树+manacher)
题目链接:https://cn.vjudge.net/contest/283743#problem/B 题目大意:给你n个字符串,然后问你将这位n个字符串任意两两组合,然后问你这所有的n*n种情况中, ...
- Debian 安装配置(包括kdevelop)
最近几天折腾了一下Debian 7 (gnome桌面DVD版,KDE桌面CD版最后会提到),总的来说收获还是挺大的,对比以前使用ubuntu,debian 7给我的感觉像是一个新生婴儿,不带多余的花俏 ...
- SpringBoot PUT请求
(1)配置HiddenHttpMethodFilter(SpringMVC需要配置,SpringBoot已经为我们自动配置了) (2)在视图页面创建一个Post Form表单,在表单中创建一个inpu ...