文章目录
主要内容:
- 使用<script>元素
- 行内脚本与外部脚本的比较
- 文档模式对JavaScript的影响
- 确保JavaScript不可用时的用户体验
2.1script元素
8个属性:
- async:规定异步执行脚本(仅适用于外部脚本)。
- charset:使用src属性指定的字符集。【很少使用】
- crossorigin:配置相关请求的CORS(跨源资源共享)设置。默认不使用。
https://blog.csdn.net/qq_40028324/article/details/107076751 - defer:表示在文档解析和显示完成后在执行脚本是没问题的。
- integrity:防止文件被劫持篡改 用来校验使用的。
- language:废弃
- src:指定要执行的JS文件。
- type:代码块中脚本语言的内容类型。按照惯例,这个值始终都是“text/javascript”.
script元素使用
1、在网页中嵌入JavaScript代码
2、在网页中包含外部JavaScript文件
注意点:
1、嵌入行内的JavaScript代码(放在<script>标签中)
- 代码中不能出现字符串<script>,需加上转译字符\<script>。
2、外部文件中的JavaScript<script src="example.js"></script>
- XHTML中</script>可以省略,但HTML中不行(在IE浏览器中将不能正常显示)。
- 不能在<script>标签中包含其他JS代码,即使有行内代码也会被忽略。
- src属性可以是一个完整的URL,其指向的资源可以跟包含它的HTML页面不在同一个域中【浏览器在解析这个资源时,会向该路径发送GET请求,以获取相应资源。改请求不受浏览器同源策略限制,但返回的JS则受限制。】
同源策略是一个重要的安全策略,它用于限制一个origin的文档或者它加载的脚本如何能与另一个源的资源进行交互。它能帮助阻隔恶意文档,减少可能被攻击的媒介。
2.1.1标签位置
- 1、放在<head>标签内
目的:把外部的CSS和JS文件集中放到一起
造成问题:意味着必须把所有JavaScript代码下载、解析和解释完成后,才开始解析到<body>,开始渲染页面。用户体验差 - 2、放在<body>元素中的页面内容后面
目的:在处理JavaScript前已完全渲染页面用户感觉页面加载变快了
2.1.2推迟执行脚本
最佳推迟执行脚本方案:将脚本放在页面底部。
**defer属性:**表示脚本在实行时不会改变页面的结构,同时告诉浏览器立即开始下载,但执行推迟。
<!DOCTYPE html>
<html>
<head>
<title>Example HTML Page</title>
<script defer src="example1.js"></script>//XHTML中应该写成defer="defer"
<script defer src="example2.js"></script>
</head>
<body>
<!-- content here -->
</body>
</html>
注:
- 虽然<script>元素包含在页面<head>中,但他们会在浏览器解析到</html>结束标签时后才执行。
- 按HTML5规范,第一个推迟脚本会在第二个之前执行,两者在DOMContentLoaded事件之前执行(但实际中不一定,最好只包含一个这样的脚本)
- defer属性支持部分浏览器,其他浏览器会忽略这个属性。
2.1.3异步执行脚本
async属性:
- 改变脚本处理方式:
与defer类似,都只使用于外部脚本,告诉浏览器立即下载。
不同点:不能保证async的脚本按照它们出现的次序执行。
<!DOCTYPE html>
<html>
<head>
<title>Example HTML Page</title>
<script async src="example1.js"></script>//XHTML中未async="async"
<script async src="example2.js"></script>
</head>
<body>
<!-- content here -->
</body>
</html>
目的:告诉浏览器不必等待脚本下载和执行完在加载页面,同样也不必等到该异步脚本下载和执行后再加载其他脚本。
- 异步脚本不应该在加载期间修改DOM
- 异步脚本保证会在页面的load事件前执行,但可能会在DOMContentLoaded事件之前或之后。
- 部分浏览器支持
好的web开发实践不推荐使用该种方法
2.1.4动态加载脚本
方法: 通过DOM中动态添加script元素来加载指定脚本
let script=document.createElement('script');
script.src='gibberish.js';
document.head.appendChild(script);
注: 默认情况下,以这种方式创建的<script>元素以异步方式加载,相对于添加了async属性。
出现问题: 所有浏览器支持createElement(),但只有部分浏览器支持async。
解决:统一动态脚本的加载行为,将其设置为同步加载
let script=document.createElement('script');
script.src='gibberish.js';
script.async=false;
document.head.appendChild(script);
出现问题:以这种方式获取的资源对浏览器的预加器是不可见,会严重影响他们在资源获取队列中的优先级
解决:在文档头部显示声明动态请求文件
<link rel="preload" href=""gibberish.js>
2.1.5XHTML中的变化
可扩展超文本标记语言:将HTML作为XML的应用重新包装的结果。
已退出历史舞台,可能遇到遗留代码【看懂】
- 必须指定type=“text/javascript”
- 以下代码块在XHTML中无效
【在HTML中解析<script>元素会应用特殊符号规则,但在XHTML中没有】
小于号(<)会被解释成一个标签的开始,且由于小于号后不能有空格而报错。
<script type="text/javascript">
function compare(a, b) {
if (a < b) {
console.log("A is less than B");
} else if (a > b) {
console.log("A is greater than B");
} else {
console.log("A is equal to B");
}
}
</script>
- 方法一:小于号(<)替换成(<)
<script type="text/javascript">
function compare(a, b) {
if (a < b) {
console.log("A is less than B");
} else if (a > b) {
console.log("A is greater than B");
} else {
console.log("A is equal to B");
}
}
</script>
- 方法二:把所有代码包含到一个CDATA块中(兼容XHTML的浏览器)
CDATA块中,可以包含任意文本的区块,其内容不作为标签来解析
<script type="text/javascript"><![CDATA[
function compare(a, b) {
if (a < b) {
console.log("A is less than B");
} else if (a > b) {
console.log("A is greater than B");
} else {
console.log("A is equal to B");
}
}
]]></script>
- 方法三:把所有代码包含到一个CDATA块中(非兼容XHTML的浏览器)
<script type="text/javascript">
//<![CDATA[
function compare(a, b) {
if (a < b) {
console.log("A is less than B");
} else if (a > b) {
console.log("A is greater than B");
} else {
console.log("A is equal to B");
}
}
//]]>
</script>
2.1.6废弃的语法
- type属性:最佳做法,不指定type属性
2.2 行内代码与外部代码
最佳实践:将JS代码存放在外部文件中
优点:可维护性、缓存、适应未来
注:
- 配置浏览器文件需重点考虑它们占多少带宽
在SPDY/HTTP2中,请求的消耗已明显降低,以轻量、独立JavaScript组件形式向客户端送达脚本。
第一个页面包含的脚本
<script src="mainA.js"></script>
<script src="component1.js"></script>
<script src="component2.js"></script>
<script src="component3.js"></script>
...
后续页面包含脚本
<script src="mainB.js"></script>
<script src="component3.js"></script>
<script src="component4.js"></script>
<script src="component5.js"></script>
...
初次请求,若浏览器支持SPDY/HTTP2,可以从同一个地方取得一批文件,并逐个放进浏览器缓存中。
第二个页面请求时,由于已经把应用程序切割成了轻量可缓存的文件,第二个页面也依赖的某些组件已经存在浏览器的缓存中。
2.3文档模式
IE5.5发明了文档模式的概念,使用doctope切换文档模式。
模式:
- 混杂模式(支持一些非标准的特性)
以省略文档开头的doctype声明为开关,这种约定并不合理不使用黑科技基本上没有浏览器一致性可言。 - 标准模式(使IE具有兼容标准的行为)
以下两种文档类型声明开启:
<script>
<!-- HTML 4.01 Strict -->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<!-- XHTML 1.0 Strict -->
<!DOCTYPE html PUBLIC
"-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!-- HTML5 -->
<!DOCTYPE html>
</script>
- 准标准模式(支持很多标准的特性,但没有标准规定的那么严格)
通过过渡性文档类型(Transitional)和(frameset)来触发。
<script>
<!-- HTML 4.01 Transitional -->
<!DOCTYPE HTML PUBLIC
"-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<!-- HTML 4.01 Frameset -->
<!DOCTYPE HTML PUBLIC
"-//W3C//DTD HTML 4.01 Frameset//EN"
"http://www.w3.org/TR/html4/frameset.dtd">
<!-- XHTML 1.0 Transitional -->
<!DOCTYPE html PUBLIC
"-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!-- XHTML 1.0 Frameset -->
<!DOCTYPE html PUBLIC
"-//W3C//DTD XHTML 1.0 Frameset//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
</script>
2.4 noscript元素
针对早期浏览器不支持JavaScript问题,被用于给不支持JavaScript的浏览器提供替代内容。
浏览器显示包含在<noscript>中的内容,两种情况:
- 浏览器不支持脚本
- 浏览器对脚本的支持被关闭