# HTML/CSS/JavaScript 基础 (Web Basics)
::: tip 🎯 核心问题
**网页是怎么做出来的?为什么有的网页只有文字,有的却像应用一样可以交互?** 这个问题会引出 Web 开发的三大基石,让你理解每一个网页背后的结构。
:::
---
## 1. 为什么要理解网页的"三剑客"?
### 1.1 从"电子海报"到"Web 应用"
想象一下你在街上看到的**海报**。你只能看,不能互动——海报不会因为你看了就改变内容,也不会因为你点了某个地方就弹出更多信息。
早期的网页就是这样的"电子海报":只能看、不能改、内容固定。
但现代网页完全不同了。它们像**桌面应用**一样:
- 你可以点击、拖拽、输入、上传
- 页面会根据你的操作实时变化
- 可以像软件一样完成复杂任务(比如在线视频剪辑)
**这种转变的核心原因,就是网页技术的三大基石:HTML + CSS + JavaScript**。
### 1.2 一个生活的比喻:盖房子
为了让你快速理解这三者的关系,我们用"盖房子"来比喻:
| 技术 | 🏠 房子比喻 | 实际作用 | 具体例子 |
| -------------- | ------------------------ | -------------------- | ------------------------------------ |
| **HTML** | 房子的**结构和材料** | 定义网页的内容和层级 | 这是一面墙、这是一扇窗、这是一个房间 |
| **CSS** | 房子的**装修和外观** | 控制网页的样式和布局 | 墙刷成蓝色、窗户放在东边、地板铺瓷砖 |
| **JavaScript** | 房子的**电器和智能系统** | 让网页具备交互和逻辑 | 按开关灯亮了、开门窗帘自动拉开 |
::: tip 💡 从表格中你能看到什么?
**HTML → CSS**: 先有房子,才能装修。HTML 是基础,CSS 是美化。没有 HTML,CSS 就没有东西可以装饰。
**HTML + CSS → JavaScript**: 先有房子和装修,才能装智能系统。JavaScript 会让"死"的页面变"活"。
**核心思想**: 三者各司其职,但缺一不可。只有 HTML 的页面很丑,只有 HTML+CSS 的页面不能互动,三者齐全才能做出像微信网页版、淘宝这样的"Web 应用"。
🎯 动手试试看:
下面这个演示展示了 HTML/CSS/JavaScript 三者如何协作。你可以切换三种模式,点击页面上的元素会高亮对应的代码:
` 这种标记,告诉浏览器"这是什么" - **元素 (Element)**: 标签 + 内容,比如 `
` 中的 `src`
- **嵌套 (Nesting)**: 标签里可以再放标签,形成父子关系
::: details 💡 点击查看:HTML 标签的"家族树"
HTML 标签之间的嵌套关系,就像一个家族树:
```html
段落
这是一个段落
```
**表单** (收集用户输入):
```html
```
**语义化标签** (HTML5 新增,让页面含义更明确):
```html
` 标签的元素都会变成红色。 **2. 喊"小组名"(类选择器 class)** ```css .highlight { background: yellow; } ``` 喊"英语课代表",可能有几个同学都是。所有 `class="highlight"` 的元素背景都会变黄。 **3. 喊"学号"(ID 选择器)** ```css #submit-btn { background: blue; } ``` 喊"2024001",全班只有一个。只有 `id="submit-btn"` 的元素会变蓝。 ::: tip 💡 优先级:谁听谁的? 如果一个元素同时被多个选择器选中,怎么办? ```html
这段文字是什么颜色?
``` ```css p { color: red; } /* 优先级: 1 */ .highlight { color: yellow; } /* 优先级: 10 */ #special-para { color: blue; } /* 优先级: 100 */ ``` **答案**: 蓝色。ID 选择器优先级最高,类选择器次之,标签选择器最低。 **内联样式**(写在 style 属性里)优先级是 1000,最高! ::: ### 3.4 CSS 的"三明治":盒模型 每个 HTML 元素在 CSS 中都被看作一个"盒子",由四层组成: ``` ┌──────────────────────────────────┐ │ margin (外边距) │ ← 盒子之间的距离 │ ┌─────────────────────────┐ │ │ │ border (边框) │ │ ← 盒子的外壳 │ │ ┌───────────────────┐ │ │ │ │ │ padding (内边距) │ │ │ ← 内容到边框的距离 │ │ │ ┌─────────────┐ │ │ │ │ │ │ │ content │ │ │ │ ← 实际内容(文字/图片) │ │ │ └─────────────┘ │ │ │ │ │ └───────────────────┘ │ │ │ └─────────────────────────┘ │ └──────────────────────────────────┘ ``` **总宽度计算**: ```css width: 200px; padding: 10px; /* 左右各 10px */ border: 5px; /* 左右各 5px */ margin: 20px; /* 左右各 20px */ ``` **元素实际占据的宽度** = 20 + 5 + 10 + 200 + 10 + 5 + 20 = **270px** ::: warning ⚠️ 常见错误:宽度对不上 新手常问:"我设置了 `width: 200px`,为什么测量出来是 270px?" 因为你没有算上 padding、border、margin! **解决方案**: ```css .box { box-sizing: border-box; /* 让 width 包含 padding 和 border */ width: 200px; padding: 10px; border: 5px; } ``` 这样,`width: 200px` 就是最终宽度,padding 和 border 会"挤"在里面。 ::: 🎯 动手试试看: 下面这个演示让你调节 padding、border 和 margin,实时看到盒模型的变化和总宽度计算:
└─一段文字
``` 这棵树就叫 **DOM 树**。每个 HTML 标签都是这棵树上的一个"节点"。 ### 5.2 为什么叫"对象模型"(Object Model)? 因为在 JavaScript 眼里,HTML 标签不仅仅是标签,而是**对象 (Object)**。它们有**属性**(可以读/写的数据)和**方法**(可以执行的动作)。 **属性 (Property)**: 节点的"数据" ```javascript imgElement.src = 'photo.jpg' // 修改图片地址 divElement.className = 'box' // 修改类名 inputElement.value = '123' // 修改输入框的值 ``` **方法 (Method)**: 节点的"动作" ```javascript buttonElement.click() // 模拟点击 divElement.remove() // 删除元素 bodyElement.appendChild(newDiv) // 添加子元素 ``` ### 5.3 怎么找节点?(DOM 查询) 就像在族谱里找人一样,JavaScript 提供了很多方法: **按"身份证"找**(ID): ```javascript const element = document.getElementById('header') // 全局唯一,速度最快 ``` **按"特征"找**(选择器): ```javascript // 找到第一个匹配的元素 const element = document.querySelector('.card h2') // 找到所有匹配的元素 const elements = document.querySelectorAll('button') ``` **按"关系"找**: ```javascript element.parentNode // 找爸爸 element.children // 找孩子 element.nextElementSibling // 找下一个兄弟 ``` ### 5.4 性能警告:不要频繁"拆家" 操作 DOM 是很**贵**的。每次你修改 DOM(比如改大小、改位置),浏览器都要: 1. **重新计算排版** (Reflow) 2. **重新绘制** (Repaint) 这两个操作都很耗时。 ::: warning ⚠️ 低效操作 ```javascript // ❌ 低效:循环 1000 次,每次都操作 DOM for (let i = 0; i < 1000; i++) { document.body.appendChild(createDiv()) } ``` **为什么会慢?** 每次appendChild,浏览器都要重新计算整页布局,1000 次就是 1000 次重排! ::: ::: tip ✅ 高效操作 ```javascript // ✅ 高效:先拼好,一次性插入 const fragment = document.createDocumentFragment() for (let i = 0; i < 1000; i++) { fragment.appendChild(createDiv()) } document.body.appendChild(fragment) // 只触发一次重排 ``` 这也正是 **Vue / React** 等现代框架诞生的原因: 它们在内存里玩"虚拟 DOM",计算好最小修改量,最后才去动真正的 DOM,从而保护了性能。 ::: 🎯 动手试试看: 下面这个演示展示了 DOM 操作的基本方法。你可以修改标题文字、切换高亮样式,并看到对应的 JavaScript 代码:点击按钮改变标题!