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属性及同源策略和跨域方法
首先介绍(同源策略) 同源策略是浏览器最核心且基本的安全约定,要求协议.域名.端口都相同为同源,如果非同源时请求数据浏览器会在控制台抛出跨域异常错误,同源策略是浏览器的行为,即使客户端请求发送了,服务 ...
随机推荐
- 10-SQL Server 2008 R2安装步骤
一. 软件和环境 1. 软件 : SQL Server 2008 R2 企业版 软件下载地址:XXXX 2. 环境要求: .Net FrameWork 3.5 以上 (windows 7 ...
- nmap扫描出现tcpwrapped
FAQ tcpwrapped From SecWiki Jump to: navigation, search What does "tcpwrapped" mean? tcpwr ...
- C# Regex正则常用方法的使用
using System; using System.Collections; using System.Configuration; using System.Data; using System. ...
- HTML5 CSS JavaScript在网页中扮演的角色
HTML (content layer) CSS (presentation layer) JavaScript (Interactive layer) 参考链接: [1] https://www.y ...
- Database学习 - mysql 数据库 外键
外键 外键约束子表的含义:如果在父表中赵达不到候选键,则不允许在子表上进行insert/update 外键预约对父表的含义:在父表上进行update/delete以更新或删除子表中有一条或多条对应匹配 ...
- 12章 搜索框架ElasticSearch介绍和整合SpringBoot 4节课
1.搜索引擎知识和搜索框架elasticsearch基本介绍 简介:通过京东电商 介绍什么是搜索引擎,和开源搜索框架ElasticSearch6.x新特性介绍 前言:介绍ES的主要特点和使用场 ...
- avloadingindicatorview 使用解析
官方文档:https://github.com/81813780/AVLoadingIndicatorView 中文文档:https://www.helplib.com/GitHub/article_ ...
- 【CXF】com.sun.xml.internal.ws.fault.ServerSOAPFaultException: Client received SOAP Faul
在客户端生成代码之后测试出现错误: com.sun.xml.internal.ws.fault.ServerSOAPFaultException: Client received SOAP Faul ...
- 解决 ionic 中的 CORS(跨域)
译者注:本人翻译功力有限,所以文中难免有翻译不准确的地方,凑合看吧,牛逼的话你看英文版的去,完事儿欢迎回来指正交流(^_^) 如果你通过 ionic serve 或者 ionic run 命令使用或 ...
- 【windows核心编程】系统消息与自定义钩子(Hook)使用
一.HOOk Hook是程序设计中最为灵活多变的技巧之一,在windows下,Hook有两种含义: 1.系统提供的消息Hook机制 2.自定义的Hook编程技巧 其中,由系统提供的消息钩子机制是由一系 ...