JavaScript <script>标签与文档模式
1. 文档模式
首先说一下文档模式吧IE5.5 发明了文档模式的概念,即可以使用 doctype 切换文档模式。最初的文档模式有两种:混杂模式和标准模式。
混杂模式让 IE 像 IE5 一样(支持一些非标准的特性)。
标准模式让 IE 具有兼容标准的行为。
2.<script>标签
script标签有以下几种元素:
- src:可选。表示包含要执行的代码的外部文件。
- async:可选。表示应该立即开始下载脚本,并在下载完后开始执行。只对外部脚本有效。
- defer:可选。表示脚本可以延迟到文档完全被解析和显示之后再执行。只对外部脚本有效,在 iE7 及更早版本中,对行内脚本也可以使用这个属性。
- charset:可选。使用src属性指定的代码字符集。这个属性很少用,因为大多数浏览器不在乎它的值。
- crossorigin:可选。配置相关请求的cors(跨域资源共享)设置。默认不使用 cors。crossorigin='anonymous’配置文件请求不必设置凭证标志。crossorigin='use-credentials’设置凭证标志,意味着出站请求会包含凭据。
- integrity:可选。允许对比接受到的资源和指定的加密签名以验证子资源的完整性。如果接收到资源的签名与这个属性指定的签名不匹配,则页面会报错,脚本不会执行。这个属性可以用于确保内容分发网络(CDN)不会提供恶意内容。
- type:可选。表示代码块中脚本语言的内容类型(也称mine类型)。
标签位置
过去所有的<script>标签都被放在header标签中,这也就意味着必须把所有JavaScript代码都下载、解析、执行完成后,才能开始渲染页面。这就导致了需要很多JavaScript的页面的首页渲染出现明显的延迟,也就是所谓的首页白屏的问题。
解决这个问题的最简单方法就是把script标签写在body的底部,等页面渲染完成后再加载js标签。
async与defer属性
除此之外,就没有别的办法了吗?不,还记的我们前面说过的这两个属性吗,他们也可以用来解决这个问题。要注意区分它们两个的区别哦。
defer属性是为了推迟执行脚本。这个属性表示在执行的时候不会改变页面的结构。也就是说,脚本会在遇到的时候立即开始下载,但是会等到整个页面都解析完毕后再运行。并且HTML5 规范要求脚本应该按照他们的顺序执行,并且会在DOMContentLoader事件之前执行。
async属性同样会告诉浏览器**立即开始下载,并且会在下载完成之后立即执行脚本。所以由于下载速度的不同,标记为async的脚本并不能保证按照他们出现的次序执行。异步脚本保证会在页面的load事件之前执行。**给脚本添加 async 的目的是告诉浏览器,不必等脚本下载完成后再加载页面,也不必等到该异步脚本下载和执行后再加载其他脚本。正因为如此,异步脚本不应该在加载期间修改DOM。
动态加载脚本文件
因为JavaScript可以使用DOM API,所以通过向 DOM 中动态添加 script 元素同样可以加载脚本。只要创建一个 script 元素并将其添加到 DOM 中即可。
let script = document.createElement('script')
script.src = 'gib.js'
script.async = 'true' //默认为true,若要设置为同步,需要手动改为false
document.head.appendChild(script)
src属性跨域
src属性可以包含来自外域的JavaScript文件。src属性可以是一个完整的url,而且这个url指向的资源可以跟包含它的HTML页面不在同一个域中。
浏览器在解析这个资源时,会向 src 属性指定路径发送一个 get请求,以取得相应的资源,假定是一个JavaScript文件。这个初始的请求不受到浏览器同源策略的限制,但返回被执行的JavaScript则受限制。当然,这个请求仍然收父页面的http/https协议的限制。
此外,说到标签跨域的问题,我这里要提一下img css文件 link标签都跟script标签一样不存在跨域问题,iframe标签存在跨域问题。