JavaScript最常见的使用方式是在HTML页面中嵌入代码。有三种方式可以在HTML中使用JavaScript。
直接在HTML标签的事件属性中编写JavaScript代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>内联JavaScript示例</title>
</head>
<body>
<button onclick="alert('你好,东巴文!')">点击我</button>
<input type="text" onfocus="this.style.backgroundColor='yellow'" onblur="this.style.backgroundColor='white'">
</body>
</html>
东巴文提醒:内联方式适合简单的交互,但不推荐在大型项目中使用,因为代码难以维护。
使用<script>标签在HTML中嵌入JavaScript代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>内部JavaScript示例</title>
<script>
function sayHello() {
alert("你好,欢迎来到东巴文!");
}
function changeColor() {
document.body.style.backgroundColor =
document.body.style.backgroundColor === "lightblue" ? "white" : "lightblue";
}
</script>
</head>
<body>
<h1>内部JavaScript示例</h1>
<button onclick="sayHello()">问好</button>
<button onclick="changeColor()">切换背景色</button>
</body>
</html>
东巴文点评:内部JavaScript适合单页面或代码量较小的情况,便于快速开发和测试。
将JavaScript代码放在独立的.js文件中,然后在HTML中引用:
script.js文件:
function sayHello() {
alert("你好,欢迎来到东巴文!");
}
function changeColor() {
document.body.style.backgroundColor =
document.body.style.backgroundColor === "lightblue" ? "white" : "lightblue";
}
console.log("外部JavaScript文件已加载");
index.html文件:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>外部JavaScript示例</title>
<script src="script.js"></script>
</head>
<body>
<h1>外部JavaScript示例</h1>
<button onclick="sayHello()">问好</button>
<button onclick="changeColor()">切换背景色</button>
</body>
</html>
东巴文推荐:外部JavaScript文件是最佳实践,便于代码复用、维护和缓存。
| 优点 | 说明 | 东巴文评价 |
|---|---|---|
| 代码分离 | HTML、CSS、JavaScript各司其职 | ✅ 结构清晰 |
| 代码复用 | 同一JS文件可被多个页面引用 | ✅ 减少重复 |
| 易于维护 | 修改JS不需要改HTML文件 | ✅ 降低耦合 |
| 浏览器缓存 | 外部文件会被浏览器缓存 | ✅ 加快加载 |
| 团队协作 | 前端工程师可以独立工作 | ✅ 提高效率 |
推荐的项目目录结构:
my-project/
├── index.html
├── css/
│ └── style.css
├── js/
│ ├── main.js
│ └── utils.js
└── images/
└── logo.png
<!-- 相对路径 -->
<script src="js/main.js"></script>
<script src="./js/main.js"></script>
<!-- 绝对路径(从网站根目录开始) -->
<script src="/js/main.js"></script>
<!-- 完整URL -->
<script src="https://cdn.example.com/library.js"></script>
东巴文提示:推荐使用相对路径,便于项目迁移。
指定外部JavaScript文件的路径:
<script src="js/main.js"></script>
指定脚本的MIME类型:
<!-- 传统写法 -->
<script type="text/javascript">
console.log("Hello");
</script>
<!-- ES6模块 -->
<script type="module">
import { greet } from './utils.js';
greet();
</script>
异步加载脚本,加载完成后立即执行:
<script async src="analytics.js"></script>
执行顺序:不保证按声明顺序执行
适用场景:独立的第三方脚本,如统计代码、广告代码
异步加载脚本,HTML解析完成后按顺序执行:
<script defer src="main.js"></script>
<script defer src="utils.js"></script>
执行顺序:按声明顺序执行
适用场景:需要操作DOM的脚本
无属性: HTML解析 → [暂停] → JS下载 → JS执行 → [继续]HTML解析
async: HTML解析 → [并行JS下载] → [暂停]JS执行 → [继续]HTML解析
defer: HTML解析 → [并行JS下载] → [完成后]JS执行
| 属性 | 加载方式 | 执行时机 | 执行顺序 | 东巴文推荐 |
|---|---|---|---|---|
| 无 | 阻塞 | 立即 | 按声明 | ❌ 放在body末尾 |
| async | 异步 | 加载后立即 | 不保证 | 第三方脚本 |
| defer | 异步 | HTML解析后 | 按声明 | ✅ 推荐使用 |
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>script标签最佳实践</title>
<!-- defer推荐放在head中 -->
<script defer src="js/main.js"></script>
<!-- async用于独立脚本 -->
<script async src="https://www.googletagmanager.com/gtag/js"></script>
</head>
<body>
<h1>页面内容</h1>
<!-- 传统方式:放在body末尾 -->
<script src="js/legacy.js"></script>
</body>
</html>
JavaScript代码按照在HTML中出现的顺序执行:
<script>
console.log("第一个脚本");
</script>
<script>
console.log("第二个脚本");
</script>
<script>
console.log("第三个脚本");
</script>
<!-- 输出顺序:第一个脚本 → 第二个脚本 → 第三个脚本 -->
<script>
// 此时DOM还未加载完成
console.log(document.getElementById("myDiv")); // null
</script>
<script defer>
// defer脚本在DOM加载完成后执行
console.log(document.getElementById("myDiv")); // <div id="myDiv">
</script>
<div id="myDiv">内容</div>
<script>
// 放在元素后面,可以访问到元素
console.log(document.getElementById("myDiv")); // <div id="myDiv">
</script>
在DOM加载完成后执行代码:
document.addEventListener("DOMContentLoaded", function() {
console.log("DOM已加载完成");
// 在这里操作DOM是安全的
const element = document.getElementById("myDiv");
element.style.color = "red";
});
在页面所有资源(图片、样式等)加载完成后执行:
window.addEventListener("load", function() {
console.log("页面所有资源已加载完成");
// 图片等资源已经加载完成,可以获取尺寸
const img = document.getElementById("myImage");
console.log(img.width, img.height);
});
| 事件/时机 | 触发条件 | 东巴文说明 |
|---|---|---|
| 脚本位置 | 解析到脚本时 | 阻塞HTML解析 |
| defer | DOM解析完成后 | 按顺序执行 |
| async | 脚本加载完成后 | 不保证顺序 |
| DOMContentLoaded | DOM构建完成 | 不等待图片 |
| load | 所有资源加载完成 | 包括图片 |
console对象提供了多种输出方法,是调试JavaScript的重要工具。
console.log("普通日志");
console.info("信息日志");
console.warn("警告日志");
console.error("错误日志");
// 字符串格式化
console.log("你好,%s!", "东巴文");
// 整数格式化
console.log("数字:%d", 42);
// 浮点数格式化
console.log("浮点数:%f", 3.14159);
// 对象格式化
const user = { name: "东巴文", age: 1 };
console.log("用户:%o", user);
const users = [
{ name: "张三", age: 25, city: "北京" },
{ name: "李四", age: 30, city: "上海" },
{ name: "王五", age: 28, city: "广州" }
];
console.table(users);
console.group("用户信息");
console.log("姓名:东巴文");
console.log("年龄:1");
console.group("详细信息");
console.log("职业:程序员");
console.log("爱好:编程");
console.groupEnd();
console.groupEnd();
console.time("数组操作");
const arr = [];
for (let i = 0; i < 100000; i++) {
arr.push(i);
}
console.timeEnd("数组操作"); // 数组操作: 5.234ms
const value = 10;
console.assert(value === 5, "value不等于5"); // 输出错误信息
console.assert(value === 10, "value不等于10"); // 不输出
console.clear();
注释是代码中不被执行的部分,用于解释代码的作用。
使用//开始,到行尾结束:
// 这是一个单行注释
console.log("Hello"); // 这也是单行注释
// 计算两个数的和
function add(a, b) {
return a + b; // 返回结果
}
使用/* */包围:
/*
* 这是一个多行注释
* 可以跨越多行
* 用于详细说明
*/
function calculateArea(width, height) {
return width * height;
}
/* 也可以写成一行 */
const PI = 3.14159;
使用/** */格式,用于生成文档:
/**
* 计算两个数的和
* @param {number} a - 第一个数
* @param {number} b - 第二个数
* @returns {number} 两个数的和
* @example
* add(1, 2) // 返回 3
*/
function add(a, b) {
return a + b;
}
/**
* 用户对象
* @typedef {Object} User
* @property {string} name - 用户名
* @property {number} age - 年龄
*/
/**
* 创建用户
* @param {string} name - 用户名
* @param {number} age - 年龄
* @returns {User} 用户对象
*/
function createUser(name, age) {
return { name, age };
}
好的注释:
// 计算斐波那契数列的第n项(使用动态规划优化)
function fibonacci(n) {
if (n <= 1) return n;
let prev = 0, curr = 1;
for (let i = 2; i <= n; i++) {
[prev, curr] = [curr, prev + curr];
}
return curr;
}
不好的注释:
// i加1
i++;
// 返回a加b
function add(a, b) {
return a + b;
}
东巴文原则:注释应该解释"为什么"而不是"是什么"。代码本身应该足够清晰,让人能看懂"是什么"。
让我们把学到的知识综合起来,创建一个完整的示例:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>第一个JavaScript程序 - 东巴文</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 600px;
margin: 50px auto;
padding: 20px;
}
.result {
margin-top: 20px;
padding: 10px;
border: 1px solid #ccc;
border-radius: 5px;
min-height: 50px;
}
button {
padding: 10px 20px;
margin: 5px;
cursor: pointer;
}
</style>
</head>
<body>
<h1>第一个JavaScript程序</h1>
<p>欢迎来到东巴文学习JavaScript!</p>
<div>
<button onclick="sayHello()">问好</button>
<button onclick="showTime()">显示时间</button>
<button onclick="changeColor()">切换颜色</button>
<button onclick="calculate()">计算</button>
</div>
<div id="result" class="result">结果将显示在这里...</div>
<script>
console.log("JavaScript程序已加载");
function sayHello() {
const result = document.getElementById("result");
result.innerHTML = "<strong>你好,欢迎来到东巴文!</strong>";
result.style.color = "green";
}
function showTime() {
const now = new Date();
const result = document.getElementById("result");
result.innerHTML = "当前时间:" + now.toLocaleString();
result.style.color = "blue";
}
function changeColor() {
const colors = ["red", "green", "blue", "orange", "purple"];
const randomColor = colors[Math.floor(Math.random() * colors.length)];
document.body.style.backgroundColor = randomColor;
document.getElementById("result").innerHTML = "背景颜色已切换为:" + randomColor;
}
function calculate() {
const a = 10;
const b = 20;
const sum = a + b;
document.getElementById("result").innerHTML =
`${a} + ${b} = ${sum}`;
}
</script>
</body>
</html>
东巴文点评:这个示例展示了JavaScript的基本用法:DOM操作、事件处理、变量、函数等。我们将在后续章节详细学习这些概念。
恭喜你完成了第一个JavaScript程序!接下来让我们深入学习:
东巴文(db-w.cn) - 让编程学习更简单
🎉 东巴文寄语:第一个程序是每个程序员的里程碑。从这行代码开始,你已经踏上了JavaScript学习之旅。在 db-w.cn,我们将陪你一起成长!