HTML中的JavaScript
JavaScript 是让网页变得生动有趣的重要语言。让我们来学习如何在 HTML 中使用 JavaScript!
<script>
元素
基本用法
<script>
元素是将 JavaScript 引入 HTML 页面的主要方法。它有8个属性:
async
:异步执行脚本defer
:延迟执行脚本crossorigin
:跨源设置integrity
:子资源完整性src
:外部脚本type
:脚本类型charset
:字符集(已废弃)language
:语言(已废弃)
使用方式
1. 内联脚本
html
<script>
function sayHi() {
console.log("Hello, world!");
}
</script>
2. 外部脚本
html
<script src="path/to/script.js"></script>
脚本加载策略
1. 传统方式
html
<!-- 放在head中,会阻塞页面渲染 -->
<head>
<script src="script.js"></script>
</head>
2. 延迟执行(defer)
html
<head>
<script defer src="script.js"></script>
</head>
3. 异步加载(async)
html
<head>
<script async src="script.js"></script>
</head>
加载顺序比较
html
<!-- 1. 普通脚本:阻塞渲染 -->
<script src="1.js"></script>
<!-- 2. defer脚本:延迟到DOM就绪后执行,按顺序 -->
<script defer src="2.js"></script>
<script defer src="3.js"></script>
<!-- 3. async脚本:异步加载,不保证顺序 -->
<script async src="4.js"></script>
<script async src="5.js"></script>
动态加载脚本
1. 创建script元素
javascript
function loadScript(url) {
let script = document.createElement('script');
script.src = url;
document.body.appendChild(script);
}
2. 处理加载事件
javascript
function loadScript(url) {
let script = document.createElement('script');
script.src = url;
script.onload = function() {
console.log('Script loaded successfully');
};
script.onerror = function() {
console.error('Script load failed');
};
document.body.appendChild(script);
}
模块加载
1. 基本用法
html
<script type="module">
import { sayHello } from './module.js';
sayHello();
</script>
2. 模块特性
javascript
// module.js
export function sayHello() {
console.log('Hello from module!');
}
// 模块自动使用严格模式
// 模块有自己的作用域
// 模块只能加载一次
XHTML中的用法
1. 传统写法
xhtml
<script type="text/javascript">
//<![CDATA[
function compare(a, b) {
if (a < b) {
console.log("a is less than b");
}
}
//]]>
</script>
2. 现代写法
html
<script>
function compare(a, b) {
if (a < b) {
console.log("a is less than b");
}
}
</script>
替代方案
1. 行内代码处理
html
<!-- 不推荐 -->
<button onclick="alert('Hello')">点击</button>
<!-- 推荐 -->
<button id="btn">点击</button>
<script>
document.getElementById('btn').addEventListener('click', () => {
alert('Hello');
});
</script>
2. 动态导入
javascript
// 按需加载模块
async function loadModule() {
const module = await import('./feature.js');
module.doSomething();
}
安全考虑
1. 内容安全策略(CSP)
html
<!-- 在服务器端设置 Content-Security-Policy 头 -->
<meta http-equiv="Content-Security-Policy"
content="script-src 'self' https://trusted.cdn.com">
2. 子资源完整性(SRI)
html
<script src="https://cdn.example.com/script.js"
integrity="sha384-hash"
crossorigin="anonymous">
</script>
最佳实践
1. 脚本位置
html
<!DOCTYPE html>
<html>
<head>
<!-- 关键脚本使用defer -->
<script defer src="critical.js"></script>
<!-- 非关键脚本使用async -->
<script async src="analytics.js"></script>
</head>
<body>
<!-- 内容优先 -->
<div id="content">...</div>
<!-- 其他脚本放在底部 -->
<script src="app.js"></script>
</body>
</html>
2. 性能优化
html
<!-- 预加载关键资源 -->
<link rel="preload" href="critical.js" as="script">
<!-- 预连接到重要域名 -->
<link rel="preconnect" href="https://api.example.com">
<!-- DNS预解析 -->
<link rel="dns-prefetch" href="https://api.example.com">
3. 错误处理
javascript
window.onerror = function(message, source, lineno, colno, error) {
console.error('JavaScript Error:', {
message,
source,
lineno,
colno,
error
});
// 发送错误报告到服务器
return true;
};
练习题
- 解释
defer
和async
的区别,并说明它们的使用场景。 - 实现一个脚本加载器,支持按顺序加载多个脚本文件。
- 说明在什么情况下应该使用动态脚本加载,以及它的优缺点。
注意事项
- 始终将脚本放在适当的位置
- 使用正确的加载策略
- 注意跨域和安全问题
- 做好错误处理
- 考虑性能优化