前端基础-HTML+CSS+JS

分类: 前端

HTML+CSS+JS基础教程

目录

  1. Web前端技术概述
  2. HTML基础
  3. CSS基础
  4. JavaScript基础
  5. DOM操作
  6. 事件处理
  7. 表单处理
  8. Ajax与Fetch API
  9. 本地存储
  10. 综合实践

一、Web前端技术概述

1.1 前端技术体系

Web前端开发主要包括三个核心技术:HTML、CSS和JavaScript。HTML负责网页的结构和内容,CSS负责网页的样式和布局,JavaScript负责网页的行为和交互。这三者相互配合,共同构成了现代Web应用的基础。

HTML(HyperText Markup Language,超文本标记语言)是用于创建网页的标准标记语言。它不是一种编程语言,而是一种标记语言,通过一系列标签来描述网页的结构和内容。HTML5是HTML的最新版本,引入了许多新的语义化标签和API,大大增强了Web应用的功能。

CSS(Cascading Style Sheets,层叠样式表)用于描述HTML文档的呈现形式。CSS3引入了许多新的特性,包括圆角、阴影、渐变、动画、过渡效果等,使得网页设计更加丰富和灵活。

JavaScript是一种脚本语言,可以在浏览器端执行,实现网页的动态交互功能。ECMAScript是JavaScript的语言规范,ES6(ECMAScript 2015)引入了许多重要的新特性,如箭头函数、类、模块、Promise等,极大地丰富了JavaScript的表达能力。

1.2 前端开发工具

现代前端开发需要掌握多种工具来提高开发效率。

工具类别 常用工具 说明
代码编辑器 VS Code、WebStorm、Sublime Text 代码编写和调试
浏览器 Chrome、Firefox、Edge 页面预览和调试
版本控制 Git、GitHub、GitLab 代码管理和协作
包管理 npm、yarn、pnpm 依赖管理
构建工具 Webpack、Vite、Rollup 代码打包和优化
框架 React、Vue、Angular UI框架
CSS预处理器 Sass、Less、Stylus CSS扩展
格式化工具 Prettier、ESLint 代码规范

VS Code是目前最流行的前端代码编辑器,拥有丰富的插件生态,支持语法高亮、代码补全、调试等功能。Chrome浏览器的开发者工具是前端调试的利器,可以检查元素、查看网络请求、调试JavaScript、分析性能等。

1.3 学习路径建议

学习Web前端建议按照以下顺序进行:首先学习HTML基础,掌握网页结构的创建方法;然后学习CSS样式,掌握页面布局和美化技巧;接着学习JavaScript基础,掌握网页交互功能的实现;最后学习前端框架和工具,提升开发效率和技能水平。

在学习过程中,建议多动手实践,通过实际项目来巩固所学知识。前端技术更新较快,需要保持持续学习的态度,关注新技术的发展趋势。


二、HTML基础

2.1 HTML文档结构

每个HTML文档都有固定的结构,包括文档类型声明、html根元素、head头部和body主体部分。

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>网页标题</title>
    <meta name="description" content="网页描述">
    <link rel="stylesheet" href="styles.css">
    <script src="script.js" defer></script>
</head>
<body>
    <h1>欢迎访问</h1>
    <p>这是一个示例网页</p>
</body>
</html>

<!DOCTYPE html>声明文档类型为HTML5,这是现代Web开发的标准。<html>是HTML文档的根元素,lang属性指定语言为中文。<head>部分包含文档的元数据,如字符编码、视口设置、标题、描述等。<body>部分包含可见的网页内容。

<meta>标签用于提供元数据信息。charset="UTF-8"指定文档使用的字符编码,确保中文正确显示。viewport元标签对响应式设计至关重要,控制页面在移动设备上的显示方式。

2.2 常用HTML标签

HTML提供了丰富的标签来创建不同类型的网页元素。

标签 说明 示例
<h1>-<h6> 标题标签 <h1>一级标题</h1>
<p> 段落标签 <p>段落文本</p>
<a> 链接标签 <a href="url">链接文本</a>
<img> 图片标签 <img src="../media/url" alt="描述">
<ul><ol> 无序/有序列表 <ul><li>项</li></ul>
<table> 表格标签 <table><tr><td>单元格</td></tr></table>
<div> 通用容器 <div>块级元素</div>
<span> 行内容器 <span>行内元素</span>
<form> 表单标签 <form action="url">...</form>
<input> 输入控件 <input type="text">
<button> 按钮 <button>点击</button>
<!-- 标题 -->
<h1>一级标题</h1>
<h2>二级标题</h2>

<!-- 段落和链接 -->
<p>这是一个段落,<a href="https://example.com">点击这里</a>访问更多内容。</p>

<!-- 列表 -->
<ul>
    <li>无序列表项1</li>
    <li>无序列表项2</li>
</ul>

<ol>
    <li>有序列表项1</li>
    <li>有序列表项2</li>
</ol>

<!-- 表格 -->
<table border="1">
    <thead>
        <tr><th>表头1</th><th>表头2</th></tr>
    </thead>
    <tbody>
        <tr><td>数据1</td><td>数据2</td></tr>
    </tbody>
</table>

2.3 语义化标签

HTML5引入了许多语义化标签,使文档结构更加清晰,对搜索引擎和辅助技术更友好。

标签 说明
<header> 页面或区块的头部
<nav> 导航区域
<main> 页面主要内容
<article> 独立文章内容
<section> 文档区块
<aside> 侧边栏内容
<footer> 页面或区块的底部
<figure><figcaption> 图像及其说明
<header>
    <nav>
        <a href="/">首页</a>
        <a href="/about">关于</a>
        <a href="/contact">联系</a>
    </nav>
</header>

<main>
    <article>
        <h1>文章标题</h1>
        <p>文章内容...</p>
    </article>

    <aside>
        <h3>相关文章</h3>
        <ul>...</ul>
    </aside>
</main>

<footer>
    <p>&copy; 2024 公司名称</p>
</footer>

2.4 表单元素

表单是Web应用中收集用户输入的重要方式。

<form action="/submit" method="POST">
    <!-- 文本输入 -->
    <label for="username">用户名:</label>
    <input type="text" id="username" name="username" required>

    <!-- 密码输入 -->
    <label for="password">密码:</label>
    <input type="password" id="password" name="password" required>

    <!-- 邮箱输入 -->
    <label for="email">邮箱:</label>
    <input type="email" id="email" name="email">

    <!-- 单选按钮 -->
    <fieldset>
        <legend>性别:</legend>
        <input type="radio" name="gender" value="male" id="male">
        <label for="male">男</label>
        <input type="radio" name="gender" value="female" id="female">
        <label for="female">女</label>
    </fieldset>

    <!-- 复选框 -->
    <input type="checkbox" name="hobby" value="reading" id="reading">
    <label for="reading">阅读</label>
    <input type="checkbox" name="hobby" value="sports" id="sports">
    <label for="sports">运动</label>

    <!-- 下拉选择 -->
    <label for="city">城市:</label>
    <select id="city" name="city">
        <option value="">请选择</option>
        <option value="beijing">北京</option>
        <option value="shanghai">上海</option>
        <option value="guangzhou">广州</option>
    </select>

    <!-- 文本域 -->
    <label for="message">留言:</label>
    <textarea id="message" name="message" rows="4" cols="50"></textarea>

    <!-- 提交按钮 -->
    <button type="submit">提交</button>
    <button type="reset">重置</button>
</form>

input元素的type属性决定了输入控件的类型,包括text(文本)、password(密码)、email(邮箱)、number(数字)、date(日期)、checkbox(复选框)、radio(单选按钮)、file(文件上传)等。


三、CSS基础

3.1 CSS基本语法

CSS用于控制HTML元素的外观和布局。基本语法包括选择器、属性和值。

/* 选择器 { 属性: 值; } */
h1 {
    color: blue;
    font-size: 24px;
    text-align: center;
}

p {
    line-height: 1.6;
    color: #333;
}

CSS选择器用于指定要样式化的HTML元素。常见的选择器类型包括元素选择器(p、div)、类选择器(.class)、ID选择器(#id)、属性选择器([type="text"])和伪类/伪元素选择器(:hover、::before)。

3.2 CSS选择器

选择器 语法 说明
元素选择器 p 选择所有p元素
类选择器 .classname 选择所有class="classname"的元素
ID选择器 #idname 选择id="idname"的元素
后代选择器 div p 选择div内的所有p元素
子选择器 div > p 选择div的直接p子元素
相邻兄弟 h1 + p 选择h1后的第一个p元素
属性选择器 [type="text"] 选择type="text"的元素
伪类 :hover 鼠标悬停状态
伪元素 ::before 元素前的内容
/* 组合选择器 */
.container .header { }       /* 后代选择器 */
.nav > li { }                /* 子选择器 */
h1, h2, h3 { }              /* 群组选择器 */

/* 属性选择器 */
input[type="text"] { }
a[href^="https"] { }        /* href以https开头 */
a[href$=".pdf"] { }         /* href以.pdf结尾 */

/* 伪类 */
a:hover { }                  /* 鼠标悬停 */
li:first-child { }          /* 第一个子元素 */
li:nth-child(2n) { }        /* 偶数子元素 */

/* 伪元素 */
p::first-line { }           /* 首行 */
p::first-letter { }         /* 首字母 */
.clearfix::after { }         /* 清除浮动 */

3.3 盒模型

盒模型是CSS布局的基础,每个HTML元素都被视为一个矩形盒子。

.box {
    /* 内容区域 */
    width: 200px;
    height: 100px;

    /* 内边距 */
    padding: 20px;

    /* 边框 */
    border: 1px solid #ccc;

    /* 外边距 */
    margin: 10px;

    /* 盒模型计算方式 */
    box-sizing: content-box;  /* 默认:width=内容宽度 */
    box-sizing: border-box;   /* width=内容+内边距+边框 */
}

盒模型包括四个部分:内容(content)、内边距(padding)、边框(border)和外边距(margin)。box-sizing属性可以改变盒模型的计算方式,border-box使元素的总宽度包含内边距和边框,通常更符合直觉。

3.4 Flexbox布局

Flexbox(弹性盒布局)是一种强大的CSS布局模式,特别适合一维布局。

<div class="container">
    <div class="item">1</div>
    <div class="item">2</div>
    <div class="item">3</div>
</div>
.container {
    display: flex;

    /* 主轴方向 */
    flex-direction: row;            /* row | row-reverse | column | column-reverse */

    /* 主轴对齐 */
    justify-content: center;        /* flex-start | flex-end | center | space-between | space-around */

    /* 交叉轴对齐 */
    align-items: center;           /* flex-start | flex-end | center | stretch | baseline */

    /* 换行 */
    flex-wrap: wrap;               /* nowrap | wrap | wrap-reverse */

    /* 间距 */
    gap: 20px;
}

.item {
    /* 伸展因子 */
    flex: 1;                       /* 等分剩余空间 */
    flex: 0 0 100px;              /* 不伸展 不收缩 固定宽度 */
}

Flex布局涉及两个轴:主轴(main axis)和交叉轴(cross axis)。flex-direction决定主轴方向,justify-content控制主轴对齐,align-items控制交叉轴对齐。

3.5 Grid布局

CSS Grid是二维布局系统,适合创建复杂的网格布局。

<div class="grid-container">
    <div class="header">Header</div>
    <div class="sidebar">Sidebar</div>
    <div class="main">Main Content</div>
    <div class="footer">Footer</div>
</div>
.grid-container {
    display: grid;

    /* 定义列和行 */
    grid-template-columns: 200px 1fr 200px;
    grid-template-rows: auto 1fr auto;

    /* 区域命名 */
    grid-template-areas:
        "header header header"
        "sidebar main aside"
        "footer footer footer";

    /* 间距 */
    gap: 20px;
}

.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.footer { grid-area: footer; }

Grid布局特别适合整体页面布局,可以轻松创建常见的Header-Sidebar-Main-Footer布局模式。grid-template-areas属性提供了一种非常直观的布局定义方式。

3.6 CSS常用属性

/* 文本样式 */
.text {
    color: #333;
    font-size: 16px;
    font-family: "Microsoft YaHei", sans-serif;
    font-weight: bold;
    text-align: center;
    line-height: 1.6;
    text-decoration: none;
    text-transform: uppercase;
}

/* 背景 */
.background {
    background-color: #f0f0f0;
    background-image: url("bg.jpg");
    background-repeat: no-repeat;
    background-position: center;
    background-size: cover;
}

/* 边框和圆角 */
.border {
    border: 1px solid #ccc;
    border-radius: 8px;
    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}

/* 定位 */
.position {
    position: relative;     /* relative | absolute | fixed | sticky */
    top: 10px;
    left: 20px;
    z-index: 100;
}

/* 过渡和动画 */
.animation {
    transition: all 0.3s ease;
    animation: fadeIn 0.5s ease-in-out;
}

@keyframes fadeIn {
    from { opacity: 0; }
    to { opacity: 1; }
}

/* 变换 */
.transform {
    transform: translate(10px, 20px);  /* 移动 */
    transform: rotate(45deg);          /* 旋转 */
    transform: scale(1.5);            /* 缩放 */
    transform: skew(10deg, 20deg);    /* 倾斜 */
}

四、JavaScript基础

4.1 JavaScript简介

JavaScript是一种脚本语言,可以在浏览器中运行,也可以在服务器端运行(Node.js)。它是Web开发的核心技术之一,为网页提供了交互能力。

JavaScript的基本特点包括:解释型语言(无需编译)、动态类型(变量类型在运行时确定)、面向对象(基于原型)、函数式编程(支持高阶函数、闭包)等。

// 变量声明
let name = "张三";        // 可变变量
const age = 25;          // 常量,不可变
var oldStyle = "旧方式"; // var声明(不推荐)

// 数据类型
let number = 42;                    // 数字
let text = "Hello";                 // 字符串
let isActive = true;                // 布尔值
let array = [1, 2, 3];              // 数组
let object = { name: "李四", age: 30 };  // 对象
let empty = null;                   // 空值
let notDefined;                     // undefined

// 基本运算
let sum = 10 + 5;       // 加法
let product = 10 * 5;   // 乘法
let isEqual = 10 === 5; // 严格相等比较

// 条件语句
if (age >= 18) {
    console.log("成年人");
} else if (age >= 12) {
    console.log("青少年");
} else {
    console.log("儿童");
}

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

4.2 函数

函数是JavaScript中的核心概念,用于封装可重复使用的代码块。

// 函数声明
function greet(name) {
    return "Hello, " + name + "!";
}

// 函数表达式
const greet = function(name) {
    return "Hello, " + name + "!";
};

// 箭头函数(ES6)
const greet = (name) => "Hello, " + name + "!";

// 带默认参数的函数
function greet(name = "Guest") {
    return "Hello, " + name + "!";
}

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

// 立即执行函数表达式(IIFE)
(function() {
    console.log("立即执行");
})();

// 回调函数
function processArray(arr, callback) {
    const result = [];
    for (let item of arr) {
        result.push(callback(item));
    }
    return result;
}

const doubled = processArray([1, 2, 3], x => x * 2);
console.log(doubled); // [2, 4, 6]

4.3 对象与类

JavaScript是面向对象的语言,支持基于原型的继承。ES6引入了class语法,使面向对象编程更加清晰。

// 对象创建
const person = {
    name: "张三",
    age: 25,
    greet() {
        return `Hello, I'm ${this.name}`;
    }
};

// 访问属性
console.log(person.name);         // 点号访问
console.log(person["age"]);       // 方括号访问

// 添加/修改属性
person.gender = "male";
delete person.age;

// 类定义
class Person {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }

    greet() {
        return `Hello, I'm ${this.name}`;
    }

    // 静态方法
    static create(name, age) {
        return new Person(name, age);
    }
}

// 继承
class Student extends Person {
    constructor(name, age, grade) {
        super(name, age);  // 调用父类构造函数
        this.grade = grade;
    }

    greet() {
        return super.greet() + `, I'm in grade ${this.grade}`;
    }
}

const student = new Student("李四", 18, 10);
console.log(student.greet());

4.4 数组操作

数组是JavaScript中最常用的数据结构之一,提供了丰富的操作方法。

const arr = [1, 2, 3, 4, 5];

// 遍历
arr.forEach((item, index) => {
    console.log(index + ": " + item);
});

// map - 映射
const doubled = arr.map(x => x * 2);
console.log(doubled); // [2, 4, 6, 8, 10]

// filter - 过滤
const evens = arr.filter(x => x % 2 === 0);
console.log(evens); // [2, 4]

// reduce - 聚合
const sum = arr.reduce((acc, cur) => acc + cur, 0);
console.log(sum); // 15

// find - 查找
const found = arr.find(x => x > 3);
console.log(found); // 4

// some/every - 断言
console.log(arr.some(x => x > 3)); // true
console.log(arr.every(x => x > 0)); // true

// 排序
const unsorted = [3, 1, 4, 1, 5, 9, 2, 6];
console.log(unsorted.sort((a, b) => a - b)); // 升序

// 其他常用方法
arr.push(6);           // 末尾添加
arr.pop();             // 末尾删除
arr.shift();           // 开头删除
arr.unshift(0);        // 开头添加
arr.splice(1, 2);     // 删除/插入
arr.slice(1, 3);       // 切片
arr.concat([7, 8]);    // 合并
arr.includes(3);       // 是否包含
arr.indexOf(3);        // 查找索引

4.5 ES6+新特性

ES6(ECMAScript 2015)及后续版本引入了许多强大的新特性。

// let和const
let variable = "可変";
const constant = "不可变";

// 模板字符串
const name = "张三";
const message = `Hello, ${name}!`;

// 解构赋值
const [a, b] = [1, 2];
const { name, age } = { name: "李四", age: 25 };
const [first, ...rest] = [1, 2, 3, 4, 5];

// 展开运算符
const arr1 = [1, 2, 3];
const arr2 = [...arr1, 4, 5];
const obj1 = { a: 1 };
const obj2 = { ...obj1, b: 2 };

// 可选链和空值合并
const user = { profile: { name: "张三" } };
const name = user?.profile?.name ?? "未知";

五、DOM操作

5.1 DOM概述

DOM(Document Object Model,文档对象模型)将HTML文档解析为一个树形结构,JavaScript可以通过DOM API来操作网页元素。

DOM树由节点组成,主要类型包括:元素节点(Element)、文本节点(Text)、属性节点(Attribute)、注释节点(Comment)等。

// 获取元素
document.getElementById("myId");           // ID获取
document.getElementsByClassName("myClass"); // 类名获取(返回集合)
document.getElementsByTagName("div");       // 标签名获取(返回集合)
document.querySelector(".myClass");        // CSS选择器(返回第一个)
document.querySelectorAll("div.item");     // CSS选择器(返回所有)

// 获取和设置属性
const link = document.querySelector("a");
console.log(link.getAttribute("href"));    // 获取属性
link.setAttribute("href", "https://new-url.com"); // 设置属性
link.href = "https://new-url.com";         // 直接访问

// 检查元素
element.classList.add("active");           // 添加类
element.classList.remove("active");        // 移除类
element.classList.toggle("active");        // 切换类
element.classList.contains("active");       // 检查类

5.2 创建和修改元素

// 创建元素
const newDiv = document.createElement("div");
newDiv.textContent = "新元素";
newDiv.className = "new-class";

// 添加到DOM
document.body.appendChild(newDiv);         // 末尾添加
parentElement.insertBefore(newDiv, ref);   // 指定位置添加

// 插入HTML
container.innerHTML = "<p>HTML内容</p>";    // 设置HTML
container.insertAdjacentHTML("beforeend", "<p>末尾</p>");
/*
beforebegin - 元素前面
afterbegin - 元素内部开头
beforeend - 元素内部末尾
afterend - 元素后面
*/

// 删除和替换
element.remove();                          // 删除元素
parent.replaceChild(newElement, oldElement); // 替换元素

5.3 样式操作

// 内联样式
element.style.color = "red";
element.style.backgroundColor = "#f0f0f0";
element.style.cssText = "color: red; font-size: 16px;";

// 计算样式(只读)
const computedStyle = window.getComputedStyle(element);
console.log(computedStyle.width);
console.log(computedStyle.fontSize);

// 获取元素尺寸和位置
element.getBoundingClientRect(); // 返回 {top, right, bottom, left, width, height}
element.offsetWidth;             // 元素宽度
element.offsetHeight;            // 元素高度
element.clientWidth;            // 内容区+内边距
element.scrollTop;               // 滚动位置

六、事件处理

6.1 事件监听

事件是用户与网页交互时产生的动作,如点击、鼠标移动、键盘输入等。

// 添加事件监听
element.addEventListener("click", function(event) {
    console.log("元素被点击");
});

// 箭头函数形式
element.addEventListener("click", (event) => {
    console.log(event.target);
});

// 事件处理函数
function handleClick(event) {
    console.log("点击了");
    console.log(event.type);        // 事件类型
    console.log(event.target);      // 触发事件的元素
    console.log(event.currentTarget); // 绑定事件的元素
}

element.addEventListener("click", handleClick);

// 移除事件监听
element.removeEventListener("click", handleClick);

// 只执行一次
element.addEventListener("click", handler, { once: true });

6.2 常见事件类型

类别 事件 说明
鼠标事件 click 点击
鼠标事件 dblclick 双击
鼠标事件 mousedown/mouseup 鼠标按下/抬起
鼠标事件 mouseenter/mouseleave 鼠标进入/离开
鼠标事件 mousemove 鼠标移动
键盘事件 keydown 键按下
键盘事件 keyup 键抬起
键盘事件 keypress 字符键按下
表单事件 submit 表单提交
表单事件 change 值改变
表单事件 input 输入
表单事件 focus/blur 获得/失去焦点
窗口事件 load 页面加载完成
窗口事件 resize 窗口大小改变
窗口事件 scroll 滚动

6.3 事件传播

事件传播分为三个阶段:捕获阶段(从根节点到目标元素)、目标阶段(在目标元素上触发)、冒泡阶段(从目标元素到根节点)。

// 冒泡(默认)
element.addEventListener("click", handler);

// 捕获
element.addEventListener("click", handler, true);

// 阻止冒泡
event.stopPropagation();

// 阻止默认行为
event.preventDefault();

// 事件委托(性能优化)
document.getElementById("list").addEventListener("click", (event) => {
    if (event.target.tagName === "LI") {
        console.log("点击了列表项:", event.target.textContent);
    }
});

七、 表单处理

7.1 表单验证

const form = document.querySelector("form");

form.addEventListener("submit", (event) => {
    event.preventDefault();  // 阻止默认提交

    // 获取表单数据
    const formData = new FormData(form);
    const data = Object.fromEntries(formData);

    // 手动验证
    let isValid = true;

    if (!data.username || data.username.length < 3) {
        showError("username", "用户名至少3个字符");
        isValid = false;
    }

    if (!data.email || !isValidEmail(data.email)) {
        showError("email", "请输入有效的邮箱地址");
        isValid = false;
    }

    if (isValid) {
        // 提交表单
        console.log("表单数据:", data);
    }
});

function showError(field, message) {
    const input = document.getElementById(field);
    input.classList.add("error");
    input.nextElementSibling.textContent = message;
}

function isValidEmail(email) {
    return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
}

7.2 实时验证

const input = document.getElementById("username");
const errorMsg = document.getElementById("username-error");

input.addEventListener("input", () => {
    const value = input.value;

    if (value.length < 3) {
        input.classList.add("invalid");
        input.classList.remove("valid");
        errorMsg.textContent = "用户名至少3个字符";
    } else if (value.length > 20) {
        input.classList.add("invalid");
        input.classList.remove("valid");
        errorMsg.textContent = "用户名最多20个字符";
    } else {
        input.classList.remove("invalid");
        input.classList.add("valid");
        errorMsg.textContent = "";
    }
});

八、Ajax与Fetch API

8.1 Fetch API

Fetch API是现代浏览器提供的网络请求接口,取代了传统的XMLHttpRequest。

// GET请求
fetch("https://api.example.com/data")
    .then(response => {
        if (!response.ok) {
            throw new Error("网络响应异常");
        }
        return response.json();
    })
    .then(data => {
        console.log(data);
    })
    .catch(error => {
        console.error("请求失败:", error);
    });

// POST请求
fetch("https://api.example.com/submit", {
    method: "POST",
    headers: {
        "Content-Type": "application/json"
    },
    body: JSON.stringify({
        name: "张三",
        age: 25
    })
})
    .then(response => response.json())
    .then(data => console.log(data));

// async/await 写法
async function fetchData() {
    try {
        const response = await fetch("https://api.example.com/data");

        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }

        const data = await response.json();
        return data;
    } catch (error) {
        console.error("请求失败:", error);
    }
}

8.2 错误处理

async function fetchWithRetry(url, options = {}, retries = 3) {
    for (let i = 0; i < retries; i++) {
        try {
            const response = await fetch(url, options);

            if (!response.ok) {
                throw new Error(`HTTP ${response.status}`);
            }

            return await response.json();
        } catch (error) {
            console.log(`尝试 ${i + 1}/${retries} 失败:`, error.message);

            if (i === retries - 1) {
                throw error;
            }
        }
    }
}

九、本地存储

9.1 localStorage

localStorage用于在浏览器中存储数据,数据永不过期。

// 存储数据
localStorage.setItem("username", "张三");
localStorage.setItem("user", JSON.stringify({ name: "张三", age: 25 }));

// 读取数据
const username = localStorage.getItem("username");
const user = JSON.parse(localStorage.getItem("user"));

// 删除数据
localStorage.removeItem("username");
localStorage.clear();  // 清除所有

// 检查支持
if (localStorage) {
    // 使用localStorage
}

// 存储对象需要序列化
const data = { items: [1, 2, 3] };
localStorage.setItem("data", JSON.stringify(data));
const parsed = JSON.parse(localStorage.getItem("data"));

9.2 sessionStorage

sessionStorage与localStorage类似,但数据只在当前会话(标签页)期间有效。

// 存储(关闭标签页后清除)
sessionStorage.setItem("tempData", "value");

// 读取
const value = sessionStorage.getItem("tempData");

// 删除
sessionStorage.removeItem("tempData");

Cookie用于在浏览器和服务器之间传递数据,有大小限制。

// 设置Cookie(需要设置过期时间)
document.cookie = "username=张三; expires=Fri, 31 Dec 2024 23:59:59 GMT; path=/";

// 读取Cookie
function getCookie(name) {
    const value = `; ${document.cookie}`;
    const parts = value.split(`; ${name}=`);
    if (parts.length === 2) {
        return parts.pop().split(";").shift();
    }
}

// 删除Cookie(设置过期时间为过去)
document.cookie = "username=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";

十、综合实践

10.1 动态列表实现

<!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>
        * { margin: 0; padding: 0; box-sizing: border-box; }
        body { font-family: "Microsoft YaHei", sans-serif; padding: 20px; }
        .container { max-width: 600px; margin: 0 auto; }
        h1 { text-align: center; margin-bottom: 20px; }
        .input-group { display: flex; gap: 10px; margin-bottom: 20px; }
        input { flex: 1; padding: 10px; border: 1px solid #ddd; border-radius: 4px; }
        button { padding: 10px 20px; background: #4CAF50; color: white; border: none; border-radius: 4px; cursor: pointer; }
        button:hover { background: #45a049; }
        ul { list-style: none; }
        li { display: flex; justify-content: space-between; align-items: center; padding: 10px; border-bottom: 1px solid #eee; }
        li.completed span { text-decoration: line-through; color: #999; }
        .delete-btn { background: #f44336; padding: 5px 10px; }
        .delete-btn:hover { background: #da190b; }
    </style>
</head>
<body>
    <div class="container">
        <h1>任务列表</h1>
        <div class="input-group">
            <input type="text" id="taskInput" placeholder="添加新任务...">
            <button id="addBtn">添加</button>
        </div>
        <ul id="taskList"></ul>
    </div>

    <script>
        const taskInput = document.getElementById("taskInput");
        const addBtn = document.getElementById("addBtn");
        const taskList = document.getElementById("taskList");

        // 从localStorage加载任务
        let tasks = JSON.parse(localStorage.getItem("tasks") || "[]");

        // 渲染任务列表
        function renderTasks() {
            taskList.innerHTML = "";
            tasks.forEach((task, index) => {
                const li = document.createElement("li");
                if (task.completed) {
                    li.classList.add("completed");
                }
                li.innerHTML = `
                    <span>${task.text}</span>
                    <div>
                        <button onclick="toggleTask(${index})">
                            ${task.completed ? "取消" : "完成"}
                        </button>
                        <button class="delete-btn" onclick="deleteTask(${index})">删除</button>
                    </div>
                `;
                taskList.appendChild(li);
            });
            localStorage.setItem("tasks", JSON.stringify(tasks));
        }

        // 添加任务
        function addTask() {
            const text = taskInput.value.trim();
            if (text) {
                tasks.push({ text, completed: false });
                taskInput.value = "";
                renderTasks();
            }
        }

        // 切换任务状态
        function toggleTask(index) {
            tasks[index].completed = !tasks[index].completed;
            renderTasks();
        }

        // 删除任务
        function deleteTask(index) {
            tasks.splice(index, 1);
            renderTasks();
        }

        // 事件监听
        addBtn.addEventListener("click", addTask);
        taskInput.addEventListener("keypress", (e) => {
            if (e.key === "Enter") addTask();
        });

        // 初始渲染
        renderTasks();
    </script>
</body>
</html>

10.2 总结

本教程涵盖了Web前端开发的基础知识,从HTML结构、CSS样式到JavaScript交互。主要内容包括:HTML文档结构和常用标签、CSS选择器和布局模型(Flexbox、Grid)、JavaScript基础语法和ES6+新特性、DOM操作和事件处理、表单验证、数据请求(Fetch API)和本地存储。通过这些基础知识的学习,您可以创建基本的交互式网页,为进一步学习前端框架打下坚实的基础。