目录


第一章:HTML —— 网页的骨架

1.1 什么是 HTML?

HTML(HyperText Markup Language,超文本标记语言)是网页的结构层。它用"标签"来描述内容:哪是标题、哪是段落、哪是图片、哪是链接。

1.2 一个最简网页

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>我的第一个网页</title>
</head>
<body>
    <h1>Hello, World!</h1>
    <p>这是我的第一个网页。</p>
</body>
</html>

逐行解释:

代码 含义
<!DOCTYPE html> 告诉浏览器"这是 HTML5 文档"
<html lang="zh-CN"> 网页根元素,lang 指定语言为中文
<head> 头部信息(给浏览器看的,不显示在页面上)
<meta charset="UTF-8"> 字符编码,防止中文乱码
<meta name="viewport" ...> 移动端适配
<title> 浏览器标签页的标题
<body> 页面主体(用户能看到的内容全在这里)

1.3 常用标签速查

文本标签
<h1>一级标题</h1>      <!-- h1~h6,数字越大字越小 -->
<h2>二级标题</h2>
<h3>三级标题</h3>

<p>这是一段文字。</p>

<span>行内文本</span>    <!-- 不换行,通常用于包裹小段文字 -->
链接 & 图片
<a href="https://www.example.com">点我跳转</a>
<a href="https://www.example.com" target="_blank">新标签页打开</a>

<img src="photo.jpg" alt="一张照片" width="300">
<!-- alt: 图片加载失败时显示的替代文字,无障碍必写 -->
列表
<!-- 无序列表 -->
<ul>
    <li>苹果</li>
    <li>香蕉</li>
    <li>橘子</li>
</ul>

<!-- 有序列表 -->
<ol>
    <li>第一步:准备材料</li>
    <li>第二步:开始制作</li>
    <li>第三步:完成</li>
</ol>
容器标签
<div>块级容器,独占一行</div>
<span>行内容器,不换行</span>

块级元素 vs 行内元素: 块级(div、p、h1)独占一行,可以设宽高;行内(span、a)不换行,宽高由内容决定。

表格
<table border="1">
    <thead>
        <tr>
            <th>姓名</th>
            <th>年龄</th>
            <th>城市</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>张三</td>
            <td>25</td>
            <td>北京</td>
        </tr>
        <tr>
            <td>李四</td>
            <td>30</td>
            <td>上海</td>
        </tr>
    </tbody>
</table>

1.4 表单 —— 和用户交互

<form action="/submit" method="POST">
    <label for="name">姓名:</label>
    <input type="text" id="name" name="name" placeholder="请输入姓名" required>

    <label for="email">邮箱:</label>
    <input type="email" id="email" name="email" placeholder="example@mail.com">

    <label for="gender">性别:</label>
    <select id="gender" name="gender">
        <option value="male"></option>
        <option value="female"></option>
    </select>

    <label>兴趣爱好:</label>
    <input type="checkbox" name="hobby" value="reading"> 阅读
    <input type="checkbox" name="hobby" value="sports"> 运动
    <input type="checkbox" name="hobby" value="music"> 音乐

    <label for="bio">个人简介:</label>
    <textarea id="bio" name="bio" rows="4" placeholder="介绍一下自己..."></textarea>

    <button type="submit">提交</button>
    <button type="reset">重置</button>
</form>

常用 input 类型:

类型 用途 示例
text 普通文本 <input type="text">
password 密码(显示为 ●●●) <input type="password">
email 邮箱(自动校验格式) <input type="email">
number 数字 <input type="number" min="0" max="100">
date 日期选择器 <input type="date">
file 文件上传 <input type="file">
radio 单选按钮 <input type="radio" name="group">
checkbox 多选框 <input type="checkbox">

1.5 HTML5 语义化标签

用有意义的标签代替 <div>,让代码更易读、对搜索引擎更友好:

<header>    <!-- 页头:logo、导航 -->
<nav>       <!-- 导航栏 -->
<main>      <!-- 主体内容 -->
<article>   <!-- 独立文章 -->
<section>   <!-- 内容分区 -->
<aside>     <!-- 侧边栏 -->
<footer>    <!-- 页脚:版权、联系方式 -->
<!-- 语义化写法 -->
<body>
    <header>
        <nav>首页 | 关于 | 联系</nav>
    </header>
    <main>
        <article>
            <h2>文章标题</h2>
            <p>文章内容...</p>
        </article>
    </main>
    <footer>
        <p>&copy; 2026 我的网站</p>
    </footer>
</body>

第二章:CSS —— 网页的皮肤

2.1 什么是 CSS?

CSS(Cascading Style Sheets,层叠样式表)负责网页的外观:颜色、字体、布局、动画等。

2.2 CSS 写在哪里?

三种方式:

<!-- 方式一:内联样式(直接写在标签上,不推荐) -->
<p style="color: red; font-size: 16px;">红色文字</p>

<!-- 方式二:内部样式表(写在 <head> 里的 <style> 标签中) -->
<style>
    p { color: blue; }
</style>

<!-- 方式三:外部样式表(推荐!写在独立的 .css 文件中) -->
<link rel="stylesheet" href="style.css">

最佳实践: 使用外部样式表,把 HTML 和 CSS 分离。

2.3 选择器 —— 选中你想要美化的元素

/* 1. 标签选择器 —— 选中所有同类标签 */
p {
    color: #333;
    line-height: 1.6;
}

/* 2. 类选择器 —— 最常用!选中带有 class 的元素 */
.highlight {
    background-color: yellow;
    font-weight: bold;
}

/* 3. ID 选择器 —— 选中唯一元素 */
#main-title {
    font-size: 32px;
    text-align: center;
}

/* 4. 后代选择器 —— 选中嵌套在内部的元素 */
nav a {
    text-decoration: none;
    color: white;
}

/* 5. 伪类选择器 —— 特殊状态 */
a:hover {           /* 鼠标悬停 */
    color: orange;
    text-decoration: underline;
}
a:visited {         /* 已访问的链接 */
    color: purple;
}
li:first-child {    /* 第一个子元素 */
    font-weight: bold;
}
li:nth-child(odd) { /* 奇数项(隔行变色) */
    background: #f0f0f0;
}

/* 6. 组合选择器 */
h1, h2, h3 {        /* 同时选中多个 */
    font-family: "Microsoft YaHei", sans-serif;
}

2.4 盒模型 —— CSS 核心概念

每个元素都是一个矩形盒子,由内到外:

┌─────────────────────────────┐
│         margin (外边距)      │
│   ┌─────────────────────┐   │
│   │   border (边框)      │   │
│   │ ┌─────────────────┐ │   │
│   │ │  padding (内边距) │ │   │
│   │ │ ┌─────────────┐ │ │   │
│   │ │ │  content    │ │ │   │
│   │ │ │  (内容区)    │ │ │   │
│   │ │ └─────────────┘ │ │   │
│   │ └─────────────────┘ │   │
│   └─────────────────────┘   │
└─────────────────────────────┘
.box {
    width: 200px;           /* 内容宽度 */
    height: 100px;          /* 内容高度 */
    padding: 20px;          /* 内边距:内容到边框的距离 */
    border: 2px solid #333; /* 边框:粗细 样式 颜色 */
    margin: 30px;           /* 外边距:元素到相邻元素的距离 */
}

⚠️ 默认盒模型下: 元素实际占用宽度 = width + padding×2 + border×2
可以用 box-sizing: border-box;width 包含 padding 和 border(推荐全局设置)。

2.5 常用 CSS 属性速查

文字与字体
.text {
    color: #333;                        /* 文字颜色 */
    font-size: 16px;                    /* 字号 */
    font-family: "Microsoft YaHei", sans-serif; /* 字体(后备) */
    font-weight: bold;                  /* 加粗:normal / bold / 100~900 */
    font-style: italic;                 /* 斜体 */
    text-align: center;                 /* 对齐:left / center / right / justify */
    text-decoration: underline;         /* 下划线:none / underline / line-through */
    line-height: 1.8;                   /* 行高(建议 1.5~2) */
    letter-spacing: 2px;                /* 字间距 */
}
背景
.bg {
    background-color: #f5f5f5;                               /* 纯色背景 */
    background-image: url("bg.jpg");                         /* 背景图片 */
    background-size: cover;                                  /* 图片铺满:cover / contain */
    background-position: center;                             /* 图片居中 */
    background-repeat: no-repeat;                            /* 不重复 */
    /* 简写 */
    background: #f5f5f5 url("bg.jpg") center/cover no-repeat;
}
边框与圆角
.card {
    border: 1px solid #ddd;       /* 边框 */
    border-radius: 8px;           /* 圆角 */
    border-radius: 50%;           /* 正圆(需配合宽高相等) */
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); /* 阴影:x偏移 y偏移 模糊 颜色 */
}
宽高与溢出
.element {
    width: 100%;                  /* 百分比相对父元素 */
    max-width: 800px;             /* 最大宽度 */
    min-height: 200px;            /* 最小高度 */
    overflow: hidden;             /* 溢出隐藏:hidden / scroll / auto */
}

2.6 布局

Flexbox(弹性布局)—— 现代布局首选
/* 父容器 */
.container {
    display: flex;
    flex-direction: row;            /* 主轴方向:row(默认) / column */
    justify-content: space-between; /* 主轴对齐:center / space-between / space-around */
    align-items: center;            /* 交叉轴对齐:center / flex-start / stretch */
    gap: 20px;                      /* 子元素间距 */
    flex-wrap: wrap;                /* 允许换行 */
}

/* 子元素 */
.item {
    flex: 1;                        /* 等分剩余空间 */
}

记忆口诀: Flex 布局,老爸设 display: flex,儿子们自动排排站。

Grid(网格布局)—— 二维布局利器
.grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr); /* 3列等宽 */
    /* grid-template-columns: 200px 1fr 1fr;  3列,第一列固定200px */
    grid-template-rows: auto;               /* 行高自动 */
    gap: 20px;                              /* 格子间距 */
}
定位
.relative {
    position: relative;   /* 相对定位:相对自己原来的位置偏移 */
    top: 10px;
    left: 20px;
}

.absolute-parent {
    position: relative;   /* 父元素设 relative,作为子元素 absolute 的参考 */
}

.absolute {
    position: absolute;   /* 绝对定位:相对最近的定位祖先 */
    top: 0;
    right: 0;
}

.fixed {
    position: fixed;      /* 固定定位:相对浏览器窗口,滚动也不动 */
    bottom: 20px;
    right: 20px;
}

.sticky {
    position: sticky;     /* 粘性定位:滚动到一定位置后固定 */
    top: 0;
}

2.7 响应式设计 —— 适配手机 & 电脑

/* 移动优先:先写手机端样式,再用媒体查询覆盖大屏 */

/* 手机(默认) */
.container {
    padding: 10px;
}

/* 平板及以上 */
@media (min-width: 768px) {
    .container {
        padding: 20px;
        max-width: 720px;
        margin: 0 auto;
    }
}

/* 桌面 */
@media (min-width: 1024px) {
    .container {
        max-width: 960px;
    }
}

/* 响应式图片 */
img {
    max-width: 100%;
    height: auto;
}

常用断点:

设备 宽度
手机 < 768px
平板 768px ~ 1024px
桌面 > 1024px

2.8 CSS 变量 & 过渡动画

/* CSS 变量(自定义属性) */
:root {
    --primary-color: #4a90d9;
    --text-color: #333;
    --spacing: 16px;
}

.button {
    background: var(--primary-color);
    color: white;
    padding: var(--spacing);
    border-radius: 6px;

    /* 过渡动画 */
    transition: all 0.3s ease;
}

.button:hover {
    background: #357abd;
    transform: scale(1.05);       /* 放大 5% */
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
}

第三章:JavaScript —— 网页的大脑

3.1 什么是 JavaScript?

JavaScript(简称 JS)是网页的行为层。它让网页"活"起来:点击按钮弹窗、表单校验、动态加载数据、游戏、动画……

3.2 JS 写在哪里?

<!-- 方式一:内部脚本(写在 <script> 标签中) -->
<script>
    console.log("Hello, World!");
</script>

<!-- 方式二:外部脚本(推荐!写在独立的 .js 文件中) -->
<script src="script.js"></script>

<!-- 方式三:内联事件(不推荐) -->
<button onclick="alert('点了!')">点我</button>

注意: <script> 放在 </body> 之前,确保 DOM 加载完再执行。

3.3 变量与数据类型

// 变量声明
let name = "小明";          // 可变变量(现代写法,推荐)
const PI = 3.14159;        // 常量,声明后不可改
// var age = 20;            // 旧的声明方式,有作用域问题,不建议用

// 基本数据类型
let str = "Hello";         // 字符串(单引号或双引号都行)
let num = 42;              // 数字(不分整数和浮点数)
let bool = true;           // 布尔值:true / false
let nothing = null;        // 空值(有意为空)
let notDefined;            // undefined(未赋值)
let bigNum = 9007199254740991n;  // BigInt(超大整数)
let sym = Symbol("id");    // Symbol(唯一标识符)

// 模板字符串(用反引号,支持换行和插值)
let greeting = `你好,${name}!今年${2026 - 2000}岁了。`;

// 类型检测
typeof "hello";   // "string"
typeof 42;        // "number"
typeof true;      // "boolean"
typeof undefined; // "undefined"
typeof null;      // "object" (历史遗留bug 🤷)

3.4 运算符

// 算术运算符:+ - * / %(取余) **(幂)
let result = 10 % 3;  // 1
let square = 2 ** 3;  // 8

// 比较运算符:> < >= <= == === != !==
5 == "5";   // true  (值相等,自动类型转换)
5 === "5";  // false (值和类型都相等,推荐用 ===)

// 逻辑运算符:&&(与) ||(或) !(非)
let isAdult = age >= 18 && hasID;

// 三元运算符
let status = age >= 18 ? "成年人" : "未成年人";

3.5 条件与循环

// if-else
let score = 85;
if (score >= 90) {
    console.log("优秀");
} else if (score >= 60) {
    console.log("及格");
} else {
    console.log("不及格");
}

// switch
let day = 3;
switch (day) {
    case 1:
        console.log("周一");
        break;
    case 2:
        console.log("周二");
        break;
    default:
        console.log("其他");
}

// for 循环
for (let i = 0; i < 5; i++) {
    console.log(`${i + 1}`);
}

// while 循环
let count = 0;
while (count < 3) {
    console.log(count);
    count++;
}

// for...of(遍历数组 —— 推荐)
let fruits = ["🍎", "🍌", "🍊"];
for (let fruit of fruits) {
    console.log(fruit);
}

3.6 函数

// 函数声明
function sayHello(name) {
    return `你好,${name}`;
}
console.log(sayHello("小明"));  // "你好,小明!"

// 箭头函数(现代简写)
const add = (a, b) => a + b;
const greet = name => `Hi, ${name}`;
const square = x => x * x;

// 默认参数
function order(item, quantity = 1) {
    return `订购 ${quantity}${item}`;
}
console.log(order("奶茶"));      // "订购 1 份奶茶"
console.log(order("奶茶", 3));   // "订购 3 份奶茶"

3.7 数组 & 对象

// ========== 数组 ==========
let fruits = ["苹果", "香蕉", "橘子"];

// 常用方法
fruits.push("草莓");          // 尾部添加 → ["苹果", "香蕉", "橘子", "草莓"]
fruits.pop();                // 尾部删除 → 返回 "草莓"
fruits.unshift("西瓜");      // 头部添加
fruits.shift();              // 头部删除
fruits.indexOf("香蕉");      // 查找索引 → 1
fruits.includes("苹果");     // 是否存在 → true
fruits.length;               // 长度 → 3
fruits.slice(0, 2);          // 切片 → ["苹果", "香蕉"](不改变原数组)
fruits.splice(1, 1, "葡萄"); // 替换:从索引1开始删1个,插入"葡萄"

// 高阶遍历(精华!)
let nums = [1, 2, 3, 4, 5];

nums.map(n => n * 2);        // [2, 4, 6, 8, 10]    —— 映射:每个元素变形
nums.filter(n => n > 2);     // [3, 4, 5]           —— 过滤:留下满足条件的
nums.find(n => n > 3);       // 4                   —— 查找第一个满足的
nums.reduce((sum, n) => sum + n, 0); // 15           —— 累加
nums.some(n => n > 4);       // true                —— 是否存在
nums.every(n => n > 0);      // true                —— 全部满足
nums.forEach(n => console.log(n)); // 遍历(无返回值)


// ========== 对象 ==========
let person = {
    name: "小明",
    age: 25,
    city: "北京",
    // 方法(对象里的函数)
    introduce() {
        return `我叫${this.name},今年${this.age}`;
    }
};

// 访问属性
person.name;        // "小明"
person["age"];      // 25

// 增删改
person.job = "程序员";       // 新增
person.age = 26;             // 修改
delete person.city;          // 删除

// 遍历对象
for (let key in person) {
    console.log(`${key}: ${person[key]}`);
}

// 解构赋值(ES6 超实用!)
let { name, age } = person;
console.log(name, age);  // "小明" 26

let colors = ["红", "绿", "蓝"];
let [first, second] = colors;
console.log(first);  // "红"

3.8 DOM 操作 —— 用 JS 操控网页

DOM(Document Object Model)把网页变成一棵"树",JS 可以随意增删改查。

// ===== 获取元素 =====
let title = document.getElementById("main-title");         // 通过 ID(单个)
let cards = document.getElementsByClassName("card");       // 通过 class(集合)
let paras = document.getElementsByTagName("p");            // 通过标签名(集合)
let btn   = document.querySelector(".btn");                // CSS 选择器(第一个)
let items = document.querySelectorAll(".item");            // CSS 选择器(所有)

// ===== 修改内容 =====
title.textContent = "新标题";                      // 纯文本(安全)
title.innerHTML = "<span>带标签的内容</span>";      // HTML(注意 XSS 风险!)

// ===== 修改样式 =====
title.style.color = "red";
title.style.fontSize = "24px";
title.classList.add("highlight");                   // 添加 class
title.classList.remove("highlight");                // 移除 class
title.classList.toggle("dark");                     // 切换 class(有则删,无则加)
title.classList.contains("highlight");              // 是否包含

// ===== 修改属性 =====
let img = document.querySelector("img");
img.src = "new-photo.jpg";
img.alt = "新照片";

let link = document.querySelector("a");
link.href = "https://new-url.com";

let input = document.querySelector("input");
input.value = "新内容";                              // 表单值
input.disabled = true;                              // 禁用
input.placeholder = "请输入...";

// ===== 创建 & 删除元素 =====
// 创建
let newDiv = document.createElement("div");
newDiv.textContent = "我是新来的";
newDiv.className = "box";
document.body.appendChild(newDiv);                  // 追加到 body 末尾

// 删除
let oldElement = document.querySelector(".old");
oldElement.remove();                                // 移除自己

3.9 事件 —— 响应用户操作

// ===== 事件监听(推荐写法) =====
let button = document.querySelector("#my-btn");

button.addEventListener("click", function(event) {
    console.log("按钮被点击了!");
    console.log(event.target);  // 被点击的元素
});

// 箭头函数写法(更简洁)
button.addEventListener("click", (e) => {
    alert("你点了我!");
});

// ===== 常用事件类型 =====
// 鼠标事件
element.addEventListener("click", fn);        // 单击
element.addEventListener("dblclick", fn);     // 双击
element.addEventListener("mouseenter", fn);   // 鼠标进入
element.addEventListener("mouseleave", fn);   // 鼠标离开
element.addEventListener("mousemove", fn);    // 鼠标移动

// 键盘事件
document.addEventListener("keydown", (e) => {
    console.log(`按下了:${e.key}`);
    if (e.key === "Escape") {
        console.log("ESC 被按下!");
    }
});

// 表单事件
input.addEventListener("input", fn);          // 输入时触发
input.addEventListener("change", fn);         // 值改变且失焦
input.addEventListener("focus", fn);          // 获得焦点
input.addEventListener("blur", fn);           // 失去焦点
form.addEventListener("submit", (e) => {
    e.preventDefault();                       // 阻止默认提交(超重要!)
    console.log("表单数据:", new FormData(e.target));
});

// 页面事件
window.addEventListener("load", fn);          // 页面完全加载
window.addEventListener("scroll", fn);        // 滚动
window.addEventListener("resize", fn);        // 窗口大小变化

// ===== 事件委托(高效处理多个子元素) =====
// 不在每个 li 上绑事件,而是绑在父元素 ul 上
document.querySelector("ul").addEventListener("click", (e) => {
    if (e.target.tagName === "LI") {
        console.log("点击了:", e.target.textContent);
    }
});

3.10 异步 —— 等一等再执行

// ===== setTimeout / setInterval =====
setTimeout(() => {
    console.log("3秒后执行");
}, 3000);

let timer = setInterval(() => {
    console.log("每秒执行一次");
}, 1000);
// clearInterval(timer);  // 停止

// ===== Promise —— 处理异步任务 =====
let fetchData = new Promise((resolve, reject) => {
    setTimeout(() => {
        let success = true;
        if (success) {
            resolve("数据拿到了!");
        } else {
            reject("出错了!");
        }
    }, 2000);
});

fetchData
    .then(data => console.log(data))   // 成功
    .catch(err => console.error(err))  // 失败
    .finally(() => console.log("结束了"));

// ===== async/await(Promise 的语法糖,推荐) =====
async function loadUser() {
    try {
        let response = await fetch("https://api.example.com/user/1");
        let user = await response.json();
        console.log(user);
    } catch (error) {
        console.error("请求失败:", error);
    }
}

// ===== Fetch API —— 发网络请求 =====
fetch("https://api.example.com/data")
    .then(res => {
        if (!res.ok) throw new Error("网络错误");
        return res.json();            // 解析 JSON
    })
    .then(data => console.log(data))
    .catch(err => console.error(err));

// POST 请求
fetch("https://api.example.com/submit", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ name: "小明", age: 25 })
});

3.11 ES6+ 常用新特性

// 展开运算符(...)
let arr1 = [1, 2, 3];
let arr2 = [4, 5, 6];
let merged = [...arr1, ...arr2];         // [1, 2, 3, 4, 5, 6]

let obj1 = { a: 1, b: 2 };
let obj2 = { ...obj1, c: 3 };            // { a: 1, b: 2, c: 3 }

// 剩余参数
function sum(...numbers) {
    return numbers.reduce((a, b) => a + b, 0);
}
sum(1, 2, 3, 4);  // 10

// 可选链(?.) —— 安全访问深层属性
let user = null;
// user.profile.name  // ❌ 报错!
user?.profile?.name;  // ✅ undefined,不报错

// 空值合并(??) —— 只在 null/undefined 时用默认值
let name = null;
let display = name ?? "匿名用户";   // "匿名用户"
// vs ||:0 ?? "默认" → 0,但 0 || "默认" → "默认"

// 模块化(ES Modules)
// file: math.js
export function add(a, b) { return a + b; }
export const PI = 3.14159;
export default function multiply(a, b) { return a * b; }

// file: main.js
import multiply, { add, PI } from "./math.js";
console.log(add(1, 2));        // 3
console.log(multiply(3, 4));   // 12

第四章:三者如何协作

4.1 分工总结

语言 比喻 负责
结构层 HTML 骨架 内容是什么
表现层 CSS 皮肤/衣服 内容长什么样
行为层 JavaScript 大脑/肌肉 内容能做什么

4.2 一个完整示例

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>三剑客协作演示</title>
    <style>
        /* CSS */
        body {
            font-family: "Microsoft YaHei", sans-serif;
            max-width: 600px;
            margin: 50px auto;
            padding: 20px;
            background: #f0f4f8;
        }
        .card {
            background: white;
            border-radius: 12px;
            padding: 30px;
            box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
            text-align: center;
        }
        .counter {
            font-size: 48px;
            font-weight: bold;
            color: #4a90d9;
            margin: 20px 0;
        }
        button {
            background: #4a90d9;
            color: white;
            border: none;
            padding: 12px 24px;
            border-radius: 8px;
            font-size: 16px;
            cursor: pointer;
            margin: 0 5px;
            transition: all 0.2s;
        }
        button:hover {
            background: #357abd;
            transform: translateY(-2px);
        }
        button:active {
            transform: translateY(0);
        }
        .reset-btn {
            background: #e0e0e0;
            color: #666;
        }
        .reset-btn:hover {
            background: #ccc;
        }
    </style>
</head>
<body>
    <!-- HTML -->
    <div class="card">
        <h2>计数器</h2>
        <div class="counter" id="counter">0</div>
        <button onclick="changeCount(1)">+1</button>
        <button onclick="changeCount(-1)">-1</button>
        <button class="reset-btn" onclick="resetCount()">重置</button>
    </div>

    <script>
        // JavaScript
        let count = 0;
        let counterEl = document.getElementById("counter");

        function changeCount(delta) {
            count += delta;
            updateDisplay();
        }

        function resetCount() {
            count = 0;
            updateDisplay();
        }

        function updateDisplay() {
            counterEl.textContent = count;
            // 根据正负变色
            if (count > 0) {
                counterEl.style.color = "#27ae60";  // 绿色
            } else if (count < 0) {
                counterEl.style.color = "#e74c3c";  // 红色
            } else {
                counterEl.style.color = "#4a90d9";  // 蓝色
            }
        }
    </script>
</body>
</html>

更多推荐