重新学习前端之HTML

HTML


一、HTML 基础概念

1. 什么是 HTML?它的基本结构是什么?

定义: HTML(HyperText Markup Language,超文本标记语言)是一种用于创建网页的标准标记语言。它通过一组预定义的标签来描述网页的内容结构,是 Web 开发的基础技术之一。

原理

  • HTML 不是编程语言,而是标记语言
  • 使用标签(Tag)来标注内容的语义和结构
  • 浏览器解析 HTML 文档,构建 DOM(文档对象模型)树,然后渲染页面

基本结构

html 复制代码
<!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>主标题</h1>
  <p>这是一个段落。</p>
</body>
</html>

结构说明

  • <!DOCTYPE html>:声明文档类型为 HTML5
  • <html>:根元素,包含整个页面内容
  • <head>:元数据区域,包含字符集、视口设置、标题等
  • <body>:可见内容区域,包含所有页面元素

常见误区

  • 混淆 HTML 与 CSS、JavaScript 的职责:HTML 负责结构,CSS 负责样式,JavaScript 负责行为
  • 忽略 lang 属性:应设置正确的语言代码,有助于屏幕阅读器和 SEO
  • <head><body> 不能嵌套错误

2. HTML 文档的标准组成部分

标准组成部分

  1. 文档类型声明(DOCTYPE):告知浏览器使用哪个 HTML 版本解析
  2. 根元素(html):整个文档的容器
  3. 头部区域 (head):
    • 字符编码声明(charset)
    • 视口设置(viewport)
    • 页面标题(title)
    • 元数据(meta)
    • 外部资源链接(link、script)
  4. 主体区域(body):用户可见的所有内容

示例

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <!-- 字符编码 -->
  <meta charset="UTF-8">
  <!-- 视口设置 -->
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <!-- SEO 相关 -->
  <meta name="description" content="页面描述">
  <meta name="keywords" content="关键词1, 关键词2">
  <title>网页标题</title>
  <!-- 外部资源 -->
  <link rel="stylesheet" href="style.css">
  <link rel="icon" href="favicon.ico">
</head>
<body>
  <header>页眉</header>
  <main>主要内容</main>
  <footer>页脚</footer>
</body>
</html>

3. <!DOCTYPE> 的作用及 HTML5 意义

定义<!DOCTYPE> 是文档类型声明(Document Type Declaration),位于 HTML 文档的第一行,告知浏览器使用哪种 HTML 规范来解析页面。

作用

  • 触发浏览器的标准模式 (Standards Mode),而非怪异模式(Quirks Mode)
  • 确保浏览器按照 W3C 标准渲染页面
  • 避免不同浏览器之间的渲染差异

HTML4 与 HTML5 的对比

特性 HTML 4.01 HTML5
声明语法 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <!DOCTYPE html>
复杂度 冗长,基于 SGML 简洁,不再基于 SGML
大小写 不区分大小写 不区分大小写
作用 指向 DTD 文档 仅触发标准模式

HTML5 DOCTYPE 的意义

  1. 极简设计 :只需 <!DOCTYPE html>,易于记忆和编写
  2. 向后兼容:所有现代浏览器都支持
  3. 不再依赖 DTD:HTML5 不再基于 SGML,不需要 DTD 引用
  4. 触发标准模式:确保一致的渲染行为

常见误区

  • 认为 DOCTYPE 是 HTML 标签:它不是标签,是声明
  • 省略 DOCTYPE 会导致怪异模式:在怪异模式下,浏览器会模拟旧版行为,导致布局异常

怪异模式示例

html 复制代码
<!-- 没有 DOCTYPE,触发怪异模式 -->
<html>
<head><title>怪异模式</title></head>
<body>
  <div style="width: 50%; margin: 0 auto;">
    <!-- 在怪异模式下,盒模型计算方式不同 -->
  </div>
</body>
</html>

二、HTML5 新特性

4. HTML5 主要新特性有哪些?

定义: HTML5 是 HTML 的第五个重大版本,于 2014 年成为 W3C 推荐标准。它引入了大量新特性,旨在改善 Web 应用开发体验。

主要新特性分类

(1)语义化标签
html 复制代码
<header>、<nav>、<main>、<section>、<article>、
<aside>、<footer>、<figure>、<figcaption>、
<time>、<mark>、<details>、<summary>
(2)多媒体支持
html 复制代码
<!-- 原生音频 -->
<audio controls>
  <source src="audio.mp3" type="audio/mpeg">
</audio>

<!-- 原生视频 -->
<video width="640" height="480" controls>
  <source src="video.mp4" type="video/mp4">
</video>
(3)Canvas 绘图
html 复制代码
<canvas id="myCanvas" width="200" height="100"></canvas>
<script>
  const canvas = document.getElementById('myCanvas');
  const ctx = canvas.getContext('2d');
  ctx.fillStyle = '#FF0000';
  ctx.fillRect(0, 0, 150, 75);
</script>
(4)表单增强
html 复制代码
<!-- 新输入类型 -->
<input type="email" required>
<input type="url" placeholder="请输入网址">
<input type="date" min="2024-01-01">
<input type="number" min="0" max="100" step="5">
<input type="range" min="0" max="100">
<input type="search" placeholder="搜索...">
<input type="tel" pattern="[0-9]{11}">

<!-- 新属性 -->
<input type="text" placeholder="提示文字" autofocus>
<input type="text" autocomplete="on">
<input type="text" form="myForm">

<!-- 新元素 -->
<datalist id="browsers">
  <option value="Chrome">
  <option value="Firefox">
</datalist>
<input list="browsers" name="browser">
(5)Web Storage
javascript 复制代码
// localStorage(持久化)
localStorage.setItem('key', 'value');
localStorage.getItem('key');

// sessionStorage(会话级)
sessionStorage.setItem('temp', 'data');
sessionStorage.getItem('temp');
(6)Web Workers
javascript 复制代码
// 主线程
const worker = new Worker('worker.js');
worker.postMessage('start');
worker.onmessage = (e) => console.log(e.data);

// worker.js
onmessage = (e) => {
  // 执行耗时操作
  postMessage('done');
};
(7)WebSocket
javascript 复制代码
const ws = new WebSocket('ws://localhost:8080');
ws.onopen = () => ws.send('Hello');
ws.onmessage = (e) => console.log(e.data);
(8)拖放 API
html 复制代码
<div draggable="true" ondragstart="drag(event)">可拖拽元素</div>
<div ondrop="drop(event)" ondragover="allowDrop(event)">放置区域</div>
(9)地理位置 API
javascript 复制代码
navigator.geolocation.getCurrentPosition(
  (pos) => console.log(pos.coords.latitude, pos.coords.longitude)
);
(10)新增属性
  • contenteditable:使元素可编辑
  • data-*:自定义数据属性
  • hidden:隐藏元素
  • download:链接下载属性

浏览器兼容处理策略

html 复制代码
<!-- 1. 条件注释(IE 专用) -->
<!--[if lt IE 9]>
  <script src="html5shiv.js"></script>
<![endif]-->

<!-- 2. JavaScript 特性检测 -->
<script>
  if (!('placeholder' in document.createElement('input'))) {
    // 降级方案:使用 polyfill
  }
</script>

<!-- 3. CSS 渐进增强 -->
<input type="email" required>
<style>
  input:valid { border-color: green; }
  input:invalid { border-color: red; }
</style>

<!-- 4. Modernizr 库 -->
<script src="modernizr.js"></script>
<script>
  if (Modernizr.canvas) {
    // 使用 Canvas
  } else {
    // 降级方案
  }
</script>

三、HTML 语义化

5. 对 HTML 语义化的理解

定义: HTML 语义化是指使用恰当的 HTML 标签来表达内容的含义和结构,而不仅仅是为了视觉效果。即"用正确的标签做正确的事"。

原理

  • 每个 HTML 标签都有其特定的语义含义
  • 选择标签时应考虑内容"是什么",而不是"长什么样"
  • 语义化标签让机器(搜索引擎、屏幕阅读器等)能理解内容结构

语义化示例对比

html 复制代码
<!-- 非语义化写法 -->
<div class="header">
  <div class="nav">
    <div class="logo">Logo</div>
    <div class="menu">菜单</div>
  </div>
</div>
<div class="main-content">
  <div class="article">
    <div class="title">文章标题</div>
    <div class="content">文章内容</div>
  </div>
</div>
<div class="footer">页脚</div>

<!-- 语义化写法 -->
<header>
  <nav>
    <div class="logo">Logo</div>
    <ul>
      <li><a href="/">首页</a></li>
      <li><a href="/about">关于</a></li>
    </ul>
  </nav>
</header>
<main>
  <article>
    <h1>文章标题</h1>
    <p>文章内容</p>
  </article>
</main>
<footer>页脚</footer>

6. HTML 语义化的核心价值

价值维度

价值维度 说明 受益方
SEO 优化 搜索引擎能更好地理解页面结构,提高排名 网站运营者
可访问性 屏幕阅读器能正确解读内容,帮助残障用户 残障用户
代码可读性 开发者能更快理解页面结构,便于维护 开发团队
设备兼容 不同设备(手机、手表等)能更好地解析内容 终端用户
样式维护 减少 class 命名,CSS 选择器更简洁 前端开发者

具体场景

html 复制代码
<!-- 场景1:文章页面 -->
<article>
  <header>
    <h1>HTML5 语义化详解</h1>
    <time datetime="2024-03-15">2024年3月15日</time>
    <p>作者:张三</p>
  </header>
  <section>
    <h2>什么是语义化</h2>
    <p>语义化是...</p>
  </section>
  <section>
    <h2>语义化的好处</h2>
    <p>好处包括...</p>
  </section>
  <footer>
    <p>版权声明:...</p>
  </footer>
</article>

<!-- 场景2:侧边栏 -->
<aside>
  <h3>相关文章</h3>
  <ul>
    <li><a href="#">文章1</a></li>
    <li><a href="#">文章2</a></li>
  </ul>
</aside>

<!-- 场景3:图表 -->
<figure>
  <img src="chart.png" alt="2024年第一季度销售数据图表">
  <figcaption>图1:2024年第一季度销售数据</figcaption>
</figure>

7. HTML5 新增的语义化标签及使用场景

常用语义化标签一览

标签 含义 使用场景 数量限制
<header> 页眉/头部 页面或区域的头部,可包含 logo、导航等 每区域1个
<nav> 导航 主要导航链接组 多个
<main> 主内容 页面核心内容,每个页面唯一 1个
<section> 区块 具有主题相关内容分组 多个
<article> 文章 独立完整的内容块(文章、评论等) 多个
<aside> 侧边栏 与主内容相关但独立的内容 多个
<footer> 页脚 页面或区域的底部信息 每区域1个
<figure> 媒体容器 图片、代码、图表等 多个
<figcaption> 媒体标题 <figure> 的标题说明 每个 figure 最多1个
<time> 时间 日期、时间 多个
<mark> 高亮 需要标记的文字 多个
<details> 折叠内容 可展开/收起的内容 多个
<summary> 折叠标题 <details> 的可见标题 每个 details 1个

使用示例

html 复制代码
<!-- details/summary 折叠面板 -->
<details>
  <summary>点击查看详情</summary>
  <p>这里是隐藏的详细内容。</p>
</details>

<!-- mark 高亮文本 -->
<p>搜索结果显示:这是一段包含<mark>关键词</mark>的文本。</p>

<!-- time 时间标记 -->
<time datetime="2024-03-15T10:30:00+08:00">2024年3月15日 上午10:30</time>

<!-- figure + figcaption 图文组合 -->
<figure>
  <pre><code>
console.log('Hello World');
  </code></pre>
  <figcaption>代码示例1</figcaption>
</figure>

常见误区

  • <section> 不是 <div> 的替代品:只有当内容有明确主题时才使用 <section>
  • <article> 可以嵌套:文章内的评论也是独立的 <article>
  • <header><footer> 可在每个区块中使用,不限于页面级别

四、HTML 基础元素分类

8. 元素分类区别(行内元素、块级元素、空元素)

定义

类型 定义 特点
块级元素 独占一行的元素 默认宽度100%,可设置宽高,前后有换行
行内元素 不独占一行的元素 宽高由内容决定,设置宽高无效,不换行
空元素 没有内容的自闭合元素 没有结束标签,如 <br><img>

行内元素、块级元素及空元素的常见标签

块级元素(Block-level Elements)
html 复制代码
<div>        <!-- 通用容器 -->
<p>          <!-- 段落 -->
<h1>~<h6>    <!-- 标题 -->
<ul>、<ol>、<li> <!-- 列表 -->
<table>      <!-- 表格 -->
<form>       <!-- 表单 -->
<header>     <!-- 页眉 -->
<footer>     <!-- 页脚 -->
<section>    <!-- 区块 -->
<article>    <!-- 文章 -->
<aside>      <!-- 侧边栏 -->
<nav>        <!-- 导航 -->
<blockquote> <!-- 块引用 -->
<hr>         <!-- 水平线 -->
<pre>        <!-- 预格式化文本 -->
行内元素(Inline Elements)
html 复制代码
<span>       <!-- 通用容器 -->
<a>          <!-- 链接 -->
<strong>     <!-- 强调(重要) -->
<em>         <!-- 强调(重音) -->
<b>          <!-- 粗体 -->
<i>          <!-- 斜体 -->
<img>        <!-- 图片 -->
<br>         <!-- 换行 -->
<input>      <!-- 输入框 -->
<label>      <!-- 标签 -->
<code>       <!-- 代码 -->
<abbr>       <!-- 缩写 -->
<cite>       <!-- 引用标题 -->
空元素(Void Elements)
html 复制代码
<br>         <!-- 换行 -->
<hr>         <!-- 水平线 -->
<img>        <!-- 图片 -->
<input>      <!-- 输入框 -->
<link>       <!-- 外部资源链接 -->
<meta>       <!-- 元数据 -->
<area>       <!-- 图像映射区域 -->
<base>       <!-- 基准URL -->
<col>        <!-- 表格列 -->
<embed>      <!-- 外部内容 -->
<param>      <!-- 对象参数 -->
<source>     <!-- 媒体资源 -->
<track>      <!-- 媒体字幕 -->
<wbr>        <!-- 换行机会 -->

对比表格

特性 块级元素 行内元素
独占一行
可设置宽度/高度 否(通过 content 决定)
可设置 margin/padding 四边有效 左右有效,上下不影响布局
默认宽度 父元素100% 内容宽度
可包含子元素 可包含块级和行内元素 一般只包含行内元素
display 值 block inline

CSS 转换示例

css 复制代码
/* 块级转行内 */
a {
  display: block; /* 让链接变成块级,可设置宽高 */
  width: 200px;
  height: 50px;
}

/* 行内块元素 */
span {
  display: inline-block; /* 保留行内特性,但可设置宽高 */
  width: 100px;
  height: 100px;
}

五、HTML 全局属性

9. HTML 全局属性有哪些?

定义: 全局属性是所有 HTML 元素都可以使用的公共属性。

常用全局属性一览表

属性 说明 示例
id 元素唯一标识符 <div id="main">
class 元素的类名(可多个) <div class="box active">
style 内联 CSS 样式 <div style="color: red;">
title 元素额外信息(鼠标悬停提示) <abbr title="HyperText Markup Language">HTML</abbr>
lang 元素内容语言 <p lang="zh-CN">
hidden 隐藏元素(布尔属性) <div hidden>
tabindex Tab 键导航顺序 <button tabindex="1">
accesskey 键盘快捷键 <button accesskey="s">保存</button>
contenteditable 使元素可编辑 <div contenteditable="true">
draggable 元素可拖拽 <div draggable="true">
data-* 自定义数据属性 <div data-user-id="123">
dir 文本方向 <p dir="rtl">
spellcheck 拼写检查 <textarea spellcheck="true">
translate 是否翻译 <p translate="no">
slot Web Components 插槽 <div slot="header">

重点属性示例

html 复制代码
<!-- contenteditable 可编辑内容 -->
<div contenteditable="true">
  这段文字可以直接编辑
</div>

<!-- data-* 自定义数据 -->
<div 
  data-user-id="123"
  data-user-name="张三"
  data-role="admin"
>用户信息</div>

<script>
  const el = document.querySelector('[data-user-id]');
  console.log(el.dataset.userId);  // "123"
  console.log(el.dataset.userName); // "张三"
</script>

<!-- hidden 隐藏元素 -->
<div hidden>用户看不到这段内容</div>
<!-- 等价于 style="display: none;" -->

<!-- tabindex 控制 Tab 顺序 -->
<a href="/" tabindex="1">首页</a>
<a href="/about" tabindex="2">关于</a>
<a href="/contact" tabindex="3">联系</a>

六、src 和 href 区别

10. srchref 区别是什么?

定义

  • src(source):表示资源引入,浏览器会暂停当前文档处理,先加载并处理该资源
  • href(hypertext reference):表示超链接引用,浏览器会并行加载资源,不暂停当前文档

对比表格

特性 src href
全称 source hypertext reference
语义 引入资源,替换当前元素内容 引用资源,建立链接关系
加载行为 暂停文档解析,加载并执行资源 并行加载,不阻塞文档解析
使用场景 替换型资源 关联型资源
常用元素 <script><img><iframe><video> <link><a>

示例说明

html 复制代码
<!-- src:引入脚本,会阻塞页面解析 -->
<script src="app.js"></script>
<!-- 优化:添加 defer 或 async -->
<script src="app.js" defer></script>

<!-- src:引入图片,替换 img 元素内容 -->
<img src="photo.jpg" alt="照片">

<!-- href:引用样式表,并行加载 -->
<link rel="stylesheet" href="style.css">

<!-- href:超链接 -->
<a href="https://example.com">访问网站</a>

选择策略

  • 需要加载并执行 资源时使用 src(脚本、图片、媒体、框架)
  • 需要建立链接关系 时使用 href(样式表、锚点链接)

七、strong vs em

11. strongem 的区别是什么?

定义

属性 <strong> <em>
全称 strong importance emphasis
语义 重要性强,内容重要性更高 强调,重音强调
默认样式 粗体 斜体
屏幕阅读器 语气加重 重音读出

对比示例

html 复制代码
<!-- strong:表示内容重要性 -->
<p>警告:<strong>请勿在设备运行时打开外壳</strong></p>

<!-- em:表示语气强调 -->
<p>我<strong>真的</strong>很喜欢这个设计</p>
<!-- 改变 em 的位置可改变句子含义 -->
<p><em>你</em>今天要去吗?</p>    <!-- 强调"你" -->
<p>你<em>今天</em>要去吗?</p>    <!-- 强调"今天" -->
<p>你今天<em>要</em>去吗?</p>    <!-- 强调"要" -->

<!-- 语义化对比 -->
<!-- 正确:使用 strong 表示警告 -->
<strong>重要通知</strong>

<!-- 错误:仅为了粗体效果 -->
<p style="font-weight: bold">标题</p> <!-- 应使用 <h1>-<h6> -->

常见误区

  • <b><strong><b> 只是视觉粗体,无语义;<strong> 表示内容重要性
  • <i><em><i> 只是视觉斜体,无语义;em 表示语气强调
  • HTML5 中 <b><i> 仍有用途:<b> 用于关键字、产品名;<i> 用于术语、外语

八、img 的 alt 和 title 区别

12. imgalttitle 属性区别

定义

属性 alt title
全称 alternative text title
语义 替代文本,图片无法显示时的替代内容 额外信息,鼠标悬停时显示
显示时机 图片加载失败、屏幕阅读器读取 鼠标悬停在图片上
必要性 推荐所有图片都添加 可选
SEO 影响 直接影响 影响较小
可访问性 对无障碍访问至关重要 辅助信息

示例说明

html 复制代码
<!-- 正确用法 -->
<img 
  src="product.jpg" 
  alt="红色运动鞋,侧面视角,白色鞋底"
  title="点击查看产品详情"
>

<!-- alt 的场景 -->
<!-- 1. 图片加载失败时显示 alt 文本 -->
<!-- 2. 屏幕阅读器朗读 alt 文本 -->
<!-- 3. 搜索引擎根据 alt 理解图片内容 -->

<!-- 装饰性图片:alt 留空 -->
<img src="decorative-line.png" alt="">
<!-- 屏幕阅读器会跳过装饰性图片 -->

选择策略

  • 必须加 alt :所有 <img> 都应该有 alt 属性
  • 内容图片:alt 应描述图片内容
  • 功能图片:alt 应描述功能(如按钮图片写"提交"而非"绿色按钮")
  • 装饰图片 :alt 留空(alt=""),让屏幕阅读器跳过
  • title:补充额外信息,但非必要

九、表单元素

13. HTML 表单元素类型有哪些?

定义 : 表单元素用于收集用户输入,通过 <form> 元素包裹,包含多种输入类型。

表单控件类型一览表

html 复制代码
<!-- 基础输入类型 -->
<input type="text">          <!-- 文本输入 -->
<input type="password">      <!-- 密码输入 -->
<input type="number">        <!-- 数字输入 -->
<input type="email">         <!-- 邮箱输入 -->
<input type="url">           <!-- URL输入 -->
<input type="tel">           <!-- 电话号码输入 -->
<input type="search">        <!-- 搜索框 -->
<input type="date">          <!-- 日期选择器 -->
<input type="time">          <!-- 时间选择器 -->
<input type="month">         <!-- 月份选择器 -->
<input type="week">          <!-- 周选择器 -->
<input type="datetime-local"><!-- 本地日期时间 -->
<input type="color">         <!-- 颜色选择器 -->
<input type="range">         <!-- 滑块 -->
<input type="file">          <!-- 文件上传 -->
<input type="checkbox">      <!-- 复选框 -->
<input type="radio">         <!-- 单选框 -->

<!-- 按钮类型 -->
<input type="submit">        <!-- 提交按钮 -->
<input type="reset">         <!-- 重置按钮 -->
<input type="button">        <!-- 普通按钮 -->
<button type="submit">提交</button>

<!-- 其他表单元素 -->
<select>                     <!-- 下拉选择 -->
<option>选项1</option>
<option>选项2</option>
</select>

<textarea>多行文本</textarea> <!-- 多行文本 -->

<label>标签</label>          <!-- 输入标签 -->

<fieldset>                   <!-- 表单分组 -->
  <legend>分组标题</legend>
  <input type="text">
</fieldset>

<datalist id="list">         <!-- 预定义选项 -->
  <option value="选项1">
</datalist>
<input list="list">

<output>结果</output>        <!-- 计算结果输出 -->

<progress value="50" max="100">进度条</progress>
<meter value="0.6">计量器</meter>

表单属性

html 复制代码
<form action="/submit" method="POST" enctype="multipart/form-data">
  <!-- 常用输入属性 -->
  <input 
    type="text" 
    name="username"
    value="默认值"
    placeholder="请输入用户名"
    required          <!-- 必填 -->
    maxlength="20"    <!-- 最大长度 -->
    minlength="2"     <!-- 最小长度 -->
    pattern="[a-z]+"  <!-- 正则验证 -->
    readonly          <!-- 只读 -->
    disabled          <!-- 禁用 -->
    autofocus         <!-- 自动聚焦 -->
    autocomplete="on" <!-- 自动补全 -->
  >
</form>

14. HTML5 新增的表单控件类型有哪些?

HTML5 新增输入类型

类型 说明 示例 适用场景
email 邮箱验证 <input type="email"> 邮箱输入,移动端弹出邮箱键盘
url URL验证 <input type="url"> 网址输入
tel 电话号码 <input type="tel"> 手机号输入,支持 pattern 验证
number 数字输入 <input type="number" min="0" max="100"> 数值输入,带增减按钮
range 滑块 <input type="range" min="0" max="100"> 音量、亮度等范围选择
date 日期选择器 <input type="date"> 生日、预约日期
time 时间选择器 <input type="time"> 时间选择
datetime-local 本地日期时间 <input type="datetime-local"> 会议时间等
month 月份选择器 <input type="month"> 信用卡有效期
week 周选择器 <input type="week"> 周计划
color 颜色选择器 <input type="color"> 颜色选取
search 搜索框 <input type="search"> 搜索输入

HTML5 新增表单属性

属性 说明 示例
placeholder 输入提示 placeholder="请输入邮箱"
required 必填验证 required
autofocus 自动聚焦 autofocus
autocomplete 自动补全 autocomplete="on"
pattern 正则验证 pattern="[0-9]{11}"
min/max 最小/最大值 min="1" max="100"
step 步进值 step="5"
multiple 多值选择 multiple
form 关联表单 form="myForm"
novalidate 禁用验证 <form novalidate>

HTML5 新增表单元素

html 复制代码
<!-- datalist:带建议的下拉输入 -->
<label for="browser">选择浏览器:</label>
<input list="browsers" id="browser" name="browser">
<datalist id="browsers">
  <option value="Chrome">
  <option value="Firefox">
  <option value="Safari">
  <option value="Edge">
</datalist>

<!-- output:显示计算结果 -->
<form oninput="result.value=parseInt(a.value)+parseInt(b.value)">
  <input type="number" id="a" value="0"> +
  <input type="number" id="b" value="0"> =
  <output name="result" for="a b">0</output>
</form>

<!-- progress:进度条 -->
<progress id="uploadProgress" value="30" max="100">30%</progress>

<!-- meter:计量器 -->
<meter value="0.7" min="0" max="1" low="0.3" high="0.8" optimum="0.9">70%</meter>

15. 单选框(radio)实现分组需满足的属性条件

分组条件

  1. 同一组的单选框必须具有相同的 name 属性值
  2. 每个单选框应有不同的 value 属性值

示例说明

html 复制代码
<!-- 性别选择组(name相同) -->
<fieldset>
  <legend>性别</legend>
  <label>
    <input type="radio" name="gender" value="male"> 男
  </label>
  <label>
    <input type="radio" name="gender" value="female"> 女
  </label>
  <label>
    <input type="radio" name="gender" value="other"> 其他
  </label>
</fieldset>

<!-- 学历选择组(name相同但不同于性别组) -->
<fieldset>
  <legend>学历</legend>
  <label>
    <input type="radio" name="education" value="highschool"> 高中
  </label>
  <label>
    <input type="radio" name="education" value="bachelor"> 本科
  </label>
  <label>
    <input type="radio" name="education" value="master"> 硕士
  </label>
</fieldset>

关键点

  • name 相同 → 同组(只能选一个)
  • name 不同 → 不同组(可分别选择)
  • 建议使用 <label> 包裹或关联,提升可访问性

十、SEO 优化

16. 从 SEO 角度提出 HTML 书写注意事项

定义: SEO(Search Engine Optimization,搜索引擎优化)是通过优化网页结构和内容,提高搜索引擎排名的技术。

HTML 层面的 SEO 优化注意事项

(1)语义化标签使用
html 复制代码
<!-- 正确使用语义化标签 -->
<header>
  <nav>
    <a href="/">首页</a>
  </nav>
</header>
<main>
  <article>
    <h1>文章主标题(每页唯一)</h1>
    <section>
      <h2>小节标题</h2>
      <h3>子小节标题</h3>
    </section>
  </article>
</main>
<footer>页脚</footer>
(2)合理的标题层级
html 复制代码
<!-- 正确:层级递进 -->
<h1>网站名称</h1>
<h2>栏目名称</h2>
<h3>文章标题</h3>

<!-- 错误:跳级使用 -->
<h1>网站名称</h1>
<h3>跳过h2直接h3</h3> <!-- 不利于SEO -->
(3)Meta 标签优化
html 复制代码
<head>
  <!-- 页面标题(50-60字符) -->
  <title>页面标题 - 品牌名称</title>
  
  <!-- 页面描述(150-160字符) -->
  <meta name="description" content="准确的页面描述,包含关键词">
  
  <!-- 关键词(部分搜索引擎仍参考) -->
  <meta name="keywords" content="关键词1, 关键词2, 关键词3">
  
  <!-- 规范URL(避免重复内容) -->
  <link rel="canonical" href="https://example.com/page">
  
  <!-- Open Graph(社交媒体分享优化) -->
  <meta property="og:title" content="分享标题">
  <meta property="og:description" content="分享描述">
  <meta property="og:image" content="分享图片">
  
  <!-- robots 控制 -->
  <meta name="robots" content="index, follow">
</head>
(4)图片优化
html 复制代码
<!-- 必须添加 alt 属性 -->
<img src="product.jpg" alt="产品名称 - 红色运动鞋">

<!-- 使用 figure 包裹重要图片 -->
<figure>
  <img src="chart.png" alt="2024年Q1销售增长图表">
  <figcaption>2024年第一季度销售数据</figcaption>
</figure>
(5)结构化数据(Schema.org
html 复制代码
<!-- 使用 JSON-LD 格式 -->
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Article",
  "headline": "文章标题",
  "author": {
    "@type": "Person",
    "name": "作者名"
  },
  "datePublished": "2024-03-15"
}
</script>
(6)链接优化
html 复制代码
<!-- 有意义的链接文本 -->
<a href="/about">了解我们的团队</a>
<!-- 而不是 -->
<a href="/about">点击这里</a>

<!-- 外部链接添加 rel 属性 -->
<a href="https://example.com" rel="noopener noreferrer">外部链接</a>
(7)页面加载速度优化
html 复制代码
<!-- 预加载关键资源 -->
<link rel="preload" href="critical.css" as="style">
<link rel="preload" href="font.woff2" as="font" crossorigin>

<!-- 延迟加载非关键资源 -->
<script src="analytics.js" defer></script>

<!-- 图片懒加载 -->
<img src="placeholder.jpg" data-src="real.jpg" loading="lazy" alt="图片">

17. SEO 优化方法有哪些?

多维度 SEO 优化策略

维度 优化方法 具体实现
HTML结构 语义化标签、标题层级、Meta标签 使用 <h1>-<h6><meta description>
内容质量 原创内容、关键词密度 内容相关、自然关键词分布
页面速度 资源压缩、懒加载、缓存 图片压缩、CDN、HTTP/2
移动端适配 响应式设计、视口设置 <meta viewport>、媒体查询
链接结构 内部链接、外部链接质量 合理的锚文本、高质量外链
结构化数据 Schema.org、JSON-LD 富媒体摘要显示
无障碍访问 ARIA、alt属性 提升可访问性评分

十一、响应式设计与移动端适配

18. HTML 层面的响应式实现方法有哪些?

响应式设计原理: 响应式设计(Responsive Web Design)使网页能够根据不同设备的屏幕尺寸自动调整布局,提供最佳浏览体验。

(1)视口设置(Viewport)
html 复制代码
<!-- 必须设置:移动端适配基础 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0, user-scalable=yes">

viewport 参数说明

参数 说明 示例值
width 视口宽度 device-width
initial-scale 初始缩放比例 1.0
minimum-scale 最小缩放比例 0.5
maximum-scale 最大缩放比例 5.0
user-scalable 是否允许缩放 yes/no

常见错误

html 复制代码
<!-- 错误:未设置 viewport,导致移动端缩放异常 -->
<html>
<head>
  <title>移动端页面</title>
  <!-- 缺少 viewport -->
</head>
</html>
(2)响应式图片
html 复制代码
<!-- 方案1:srcset 根据屏幕密度 -->
<img 
  src="small.jpg"
  srcset="small.jpg 480w, medium.jpg 800w, large.jpg 1200w"
  sizes="(max-width: 480px) 100vw, (max-width: 800px) 50vw, 33vw"
  alt="响应式图片"
>

<!-- 方案2:picture 元素根据条件加载 -->
<picture>
  <source media="(max-width: 480px)" srcset="mobile.jpg">
  <source media="(max-width: 768px)" srcset="tablet.jpg">
  <img src="desktop.jpg" alt="响应式图片">
</picture>
(3)媒体查询(CSS 配合)
html 复制代码
<!-- HTML 中通过 media 属性控制样式表 -->
<link rel="stylesheet" href="mobile.css" media="screen and (max-width: 480px)">
<link rel="stylesheet" href="desktop.css" media="screen and (min-width: 769px)">
(4)相对单位使用
html 复制代码
<!-- 使用相对单位而非固定像素 -->
<div style="width: 50%; max-width: 600px;">
  <p style="font-size: 1.2rem;">相对单位文本</p>
</div>

19. 移动端适配的常用方法有哪些?

适配方法对比

方法 原理 优点 缺点 适用场景
Viewport适配 设置 viewport meta 简单直接 仅控制缩放 所有移动端页面
rem适配 根据根字号缩放 统一比例 需计算 复杂移动页面
vw/vh适配 视口单位 天然响应 兼容性 现代项目
媒体查询 断点适配 灵活控制 断点维护 响应式网站
弹性布局 Flexbox/Grid 自动分配 学习成本 各类布局

rem 适配方案

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <script>
    // 动态设置根字号
    const fontSize = window.innerWidth / 10;
    document.documentElement.style.fontSize = fontSize + 'px';
  </script>
</head>
<body>
  <div style="font-size: 0.16rem;">内容</div>
</body>
</html>

vw/vh 适配方案

html 复制代码
<style>
  /* 基于设计稿 375px 宽度 */
  .box {
    width: 50vw;           /* 占视口宽度50% */
    height: 26.67vh;       /* 占视口高度26.67% */
    font-size: 4.27vw;     /* 16px / 375px * 100vw */
  }
</style>

十二、渐进增强与优雅降级

20. 渐进增强 vs 优雅降级的区别是什么?

定义

概念 定义 设计方向
渐进增强(Progressive Enhancement) 先保证基础功能在所有浏览器可用,再为高级浏览器增强体验 自下而上
优雅降级(Graceful Degradation) 先为高级浏览器构建完整功能,再确保旧浏览器基本可用 自上而下

对比表格

维度 渐进增强 优雅降级
起点 基础功能 完整功能
目标 提升高级浏览器体验 保证旧浏览器可用
开发顺序 核心功能 → 增强功能 完整功能 → 降级方案
兼容性 更好 一般
维护成本 较低 较高
推荐度 推荐 传统做法

渐进增强示例

html 复制代码
<!-- 第一层:基础 HTML(所有设备) -->
<a href="/submit-form">提交表单</a>

<!-- 第二层:CSS 增强(支持 CSS 的设备) -->
<style>
  a {
    display: inline-block;
    padding: 10px 20px;
    background: #007bff;
    color: white;
    border-radius: 4px;
    text-decoration: none;
  }
</style>

<!-- 第三层:JavaScript 增强(支持 JS 的设备) -->
<script>
  // 使用 Ajax 提交,提供更好的体验
  document.querySelector('a').addEventListener('click', (e) => {
    e.preventDefault();
    fetch('/api/submit', { method: 'POST' })
      .then(res => res.json())
      .then(data => showSuccess());
  });
</script>

优雅降级示例

html 复制代码
<!-- 第一层:完整功能(现代浏览器) -->
<form id="contactForm">
  <input type="email" required pattern="[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$">
  <button type="submit">提交</button>
</form>

<script>
  // 现代浏览器使用 HTML5 验证 + Ajax
  const form = document.getElementById('contactForm');
  form.addEventListener('submit', (e) => {
    e.preventDefault();
    // 提交逻辑
  });
</script>

<!-- 第二层:降级方案(旧浏览器) -->
<!--[if lt IE 10]>
  <noscript>
    <p>您的浏览器不支持 JavaScript,请升级或使用表单直接提交。</p>
    <form action="/submit" method="POST">
      <input type="text" name="email">
      <button type="submit">提交</button>
    </form>
  </noscript>
<![endif]-->

选择策略

  • 新项目推荐使用渐进增强:确保核心内容可访问
  • 遗留项目可能需要优雅降级:在完整功能基础上做兼容
  • 实际开发中两者常结合使用

十三、无障碍访问(A11Y)

21. 无障碍化实现方法

定义: 无障碍访问(Accessibility,简称 A11Y)是指让残障用户也能正常使用网页的设计原则。

核心实现方法

(1)语义化标签
html 复制代码
<!-- 正确:使用语义化标签 -->
<button>点击我</button>
<a href="/">链接</a>

<!-- 错误:使用 div 模拟 -->
<div onclick="submit()">点击我</div> <!-- 无法键盘导航 -->
(2)ARIA 属性
html 复制代码
<!-- ARIA 角色 -->
<div role="navigation">
  <ul>
    <li><a href="/">首页</a></li>
  </ul>
</div>

<!-- ARIA 状态 -->
<button aria-expanded="false" aria-controls="menu">
  菜单
</button>
<ul id="menu" role="menu" aria-hidden="true">
  <li role="menuitem">选项1</li>
</ul>

<!-- ARIA 标签 -->
<input type="text" aria-label="搜索产品">

<!-- ARIA 描述 -->
<input type="password" aria-describedby="pwd-hint">
<span id="pwd-hint">密码至少8个字符</span>

<!-- ARIA 实时区域 -->
<div aria-live="polite" role="status">
  表单提交成功!
</div>
(3)键盘导航
html 复制代码
<!-- tabindex 控制焦点顺序 -->
<button tabindex="1">第一步</button>
<button tabindex="2">第二步</button>

<!-- 确保所有交互元素可聚焦 -->
<a href="/">链接</a>
<button>按钮</button>
<input type="text">
<select>
  <option>选项</option>
</select>

<!-- 非交互元素添加键盘支持 -->
<div 
  role="button" 
  tabindex="0"
  onclick="handleClick()"
  onkeydown="if(event.key==='Enter')handleClick()"
>
  可键盘操作的元素
</div>
(4)焦点管理
html 复制代码
<style>
  /* 自定义焦点样式 */
  :focus {
    outline: 2px solid #005fcc;
    outline-offset: 2px;
  }
  
  /* 移除鼠标点击时的焦点样式,保留键盘焦点 */
  :focus:not(:focus-visible) {
    outline: none;
  }
</style>
(5)颜色对比度
html 复制代码
<!-- 确保文本和背景对比度至少 4.5:1 -->
<style>
  .accessible-text {
    color: #333333;    /* 深色文本 */
    background: #ffffff; /* 白色背景 */
    /* 对比度约 12.6:1,符合 WCAG AA */
  }
</style>

常见无障碍问题及解决

问题 影响 解决方案
缺少 alt 属性 屏幕阅读器无法描述图片 添加有意义的 alt 文本
缺少表单 label 用户不知道输入什么 使用 <label> 关联
纯颜色传递信息 色盲用户无法理解 添加图标或文字说明
无键盘导航 无法使用鼠标者 确保所有功能可键盘操作
自动播放媒体 干扰辅助技术 提供暂停/停止控制

十四、HTML 空元素

22. HTML 空元素有哪些?

定义: 空元素(Void Elements),也称自闭合元素,是指没有内容、不需要结束标签的 HTML 元素。

完整列表

html 复制代码
<br>         <!-- 换行 -->
<hr>         <!-- 水平线 -->
<img>        <!-- 图片 -->
<input>      <!-- 输入控件 -->
<link>       <!-- 外部资源链接 -->
<meta>       <!-- 元数据 -->
<area>       <!-- 图像映射区域 -->
<base>       <!-- 基准URL -->
<col>        <!-- 表格列 -->
<embed>      <!-- 嵌入内容 -->
<param>      <!-- 对象参数 -->
<source>     <!-- 媒体资源 -->
<track>      <!-- 字幕轨道 -->
<wbr>        <!-- 换行机会 -->

使用示例

html 复制代码
<!-- 正确写法(HTML5) -->
<br>
<img src="photo.jpg" alt="照片">
<hr>
<input type="text">

<!-- XHTML 写法(自闭合) -->
<br />
<img src="photo.jpg" alt="照片" />

<!-- 错误写法(空元素不应有结束标签) -->
<br></br>    <!-- 错误 -->
<img src="photo.jpg"></img>  <!-- 错误 -->

十五、性能优化

23. 前端性能优化的常用方法有哪些(从 HTML、CSS、JavaScript 等多方面考虑)?

多维度优化策略

HTML 层面
html 复制代码
<!-- 1. 资源预加载 -->
<link rel="preload" href="font.woff2" as="font" crossorigin>
<link rel="prefetch" href="next-page.html">
<link rel="preconnect" href="https://fonts.googleapis.com">

<!-- 2. 图片优化 -->
<img src="small.jpg" loading="lazy" alt="图片"> <!-- 懒加载 -->

<!-- 3. 脚本加载优化 -->
<script src="app.js" defer></script>    <!-- DOM 解析完成后执行 -->
<script src="analytics.js" async></script> <!-- 下载完立即执行 -->

<!-- 4. 减少 DOM 复杂度 -->
<!-- 避免过深的嵌套,减少节点数量 -->

<!-- 5. 使用 CDN -->
<script src="https://cdn.example.com/jquery.min.js"></script>

<!-- 6. 多域名存储资源 -->
<!-- 利用浏览器并发限制,不同域名资源可并行下载 -->
<img src="https://cdn1.example.com/img1.jpg">
<img src="https://cdn2.example.com/img2.jpg">
<img src="https://cdn3.example.com/img3.jpg">

多域名存储资源的优化原理

  • 浏览器对同一域名有并发请求限制(通常 6-8 个)
  • 使用多个域名可绕过限制,实现并行下载
  • 注意:域名解析有开销,一般 2-4 个域名为宜
CSS 层面
html 复制代码
<!-- 1. 关键 CSS 内联 -->
<style>
  /* 首屏关键样式直接内联 */
  .header { background: #fff; }
</style>

<!-- 2. 非关键 CSS 异步加载 -->
<link rel="stylesheet" href="non-critical.css" media="print" onload="this.media='all'">

<!-- 3. 避免 @import -->
<!-- @import 会串行加载,应使用多个 link 标签 -->
JavaScript 层面
html 复制代码
<!-- 1. 脚本置底或 defer/async -->
<script src="app.js" defer></script>

<!-- 2. 按需加载 -->
<script>
  // 动态导入
  import('./module.js').then(module => {
    module.init();
  });
</script>

<!-- 3. 防抖与节流 -->
<script>
  // 防抖:事件触发后延迟执行
  function debounce(fn, delay) {
    let timer;
    return function(...args) {
      clearTimeout(timer);
      timer = setTimeout(() => fn.apply(this, args), delay);
    };
  }
  
  // 节流:固定时间间隔内只执行一次
  function throttle(fn, limit) {
    let inThrottle;
    return function(...args) {
      if (!inThrottle) {
        fn.apply(this, args);
        inThrottle = true;
        setTimeout(() => inThrottle = false, limit);
      }
    };
  }
</script>

24. 多域名存储资源的优化原理

原理说明

  • 浏览器对同一域名(协议 + 域名 + 端口)的并发连接数有限制
  • HTTP/1.1 标准建议最多 6 个并发连接
  • 通过将静态资源分散到多个子域名,可以突破限制

示例

html 复制代码
<!-- 单域名:受并发限制 -->
<img src="https://static.example.com/img1.jpg">
<img src="https://static.example.com/img2.jpg">
<!-- 最多同时加载6个,其余排队 -->

<!-- 多域名:突破限制 -->
<img src="https://static1.example.com/img1.jpg">
<img src="https://static2.example.com/img2.jpg">
<img src="https://static3.example.com/img3.jpg">
<img src="https://static4.example.com/img4.jpg">
<!-- 最多可同时加载约24个资源 -->

注意事项

  • HTTP/2 已支持多路复用,单域名也可并行下载
  • 多域名会增加 DNS 解析开销
  • 现代项目建议优先考虑 HTTP/2,而非多域名分片

十六、图片格式选择

25. 图片格式选择(PNG/JPG/GIF 适用场景)

格式对比

格式 特点 压缩类型 透明度 动画 适用场景
JPG/JPEG 色彩丰富,体积小 有损压缩 不支持 不支持 照片、复杂图像
PNG 无损,支持透明 无损压缩 支持 不支持 Logo、图标、截图
GIF 支持简单动画 无损压缩(256色) 支持 支持 简单动画、表情包
WebP 现代格式,体积小 有损/无损 支持 支持 通用替代
SVG 矢量,无限缩放 - 支持 支持 图标、Logo、图表
AVIF 最新格式,压缩率极高 有损/无损 支持 支持 未来通用格式

选择策略

html 复制代码
<!-- 照片类:JPG 或 WebP -->
<img src="photo.jpg" alt="风景照片">

<!-- Logo/图标:SVG 或 PNG -->
<img src="logo.svg" alt="公司Logo">

<!-- 复杂截图:PNG -->
<img src="screenshot.png" alt="软件界面截图">

<!-- 简单动画:GIF 或 WebP -->
<img src="animation.gif" alt="操作演示动画">

<!-- 响应式图片:使用 picture 元素 -->
<picture>
  <source srcset="image.avif" type="image/avif">
  <source srcset="image.webp" type="image/webp">
  <img src="image.jpg" alt="图片">
</picture>

十七、微格式

26. 什么是微格式(Microformats)?

定义: 微格式(Microformats)是一种简单的数据标记方法,通过在 HTML 中添加特定的 class 名称,使机器能理解页面内容的语义。

原理

  • 使用预定义的 class 名称标注内容
  • 基于已有的 HTML 元素,不引入新标签
  • 搜索引擎和工具可以提取结构化数据

常见微格式示例

html 复制代码
<!-- hCard:联系信息 -->
<div class="vcard">
  <span class="fn">张三</span>
  <span class="org">公司名称</span>
  <a class="email" href="mailto:zhangsan@example.com">zhangsan@example.com</a>
  <span class="tel">+86-138-0000-0000</span>
  <span class="adr">
    <span class="street-address">某街道123号</span>
    <span class="locality">北京市</span>
  </span>
</div>

<!-- hEntry:博客文章 -->
<div class="hentry">
  <h2 class="entry-title">文章标题</h2>
  <span class="published">2024-03-15</span>
  <span class="author">
    <span class="fn">作者名</span>
  </span>
  <div class="entry-content">
    <p>文章内容...</p>
  </div>
</div>

<!-- hReview:评价 -->
<div class="hreview">
  <span class="item">
    <span class="fn">产品名称</span>
  </span>
  <span class="rating">4.5</span>
  <span class="summary">很好用</span>
  <p class="description">产品使用体验...</p>
</div>

微格式与 Schema.org 对比

特性 微格式(Microformats) Schema.org
语法 HTML class 属性 HTML 属性或 JSON-LD
复杂度 简单 更丰富
支持度 逐渐减少 主流搜索引擎支持
推荐度 传统方案 推荐使用

现代替代方案(JSON-LD)

html 复制代码
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Person",
  "name": "张三",
  "email": "zhangsan@example.com",
  "telephone": "+86-138-0000-0000",
  "address": {
    "@type": "PostalAddress",
    "streetAddress": "某街道123号",
    "addressLocality": "北京市"
  }
}
</script>

十八、实战问题排查

27. 移动端视口:未设置 <meta name="viewport"> 导致缩放异常

问题描述: 在移动端浏览器中,如果没有设置 viewport meta 标签,页面会按桌面宽度渲染,导致内容缩放异常。

原因分析

  • 移动浏览器默认使用约 980px 的视口宽度
  • 页面内容会被缩小以适应屏幕
  • 文字过小,需要手动放大查看

解决方案

html 复制代码
<!-- 必须添加到 <head> 中 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0, user-scalable=yes">

参数解释

  • width=device-width:视口宽度等于设备宽度
  • initial-scale=1.0:初始缩放比例为 1:1
  • maximum-scale=5.0:最大允许放大 5 倍
  • user-scalable=yes:允许用户缩放(提升可访问性)

28. 表单验证:防抖处理或错误提示样式缺失

问题描述

  • 表单输入验证时,每次输入都触发验证,性能差且体验不佳
  • 验证失败时缺少清晰的错误提示

解决方案

html 复制代码
<!-- 防抖验证 -->
<form id="myForm">
  <div class="form-group">
    <label for="email">邮箱</label>
    <input 
      type="email" 
      id="email" 
      name="email"
      required
      pattern="[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$"
    >
    <span class="error-message" role="alert"></span>
  </div>
  <button type="submit">提交</button>
</form>

<style>
  .form-group { margin-bottom: 16px; }
  input:invalid:not(:placeholder-shown) {
    border-color: #dc3545;
  }
  input:valid:not(:placeholder-shown) {
    border-color: #28a745;
  }
  .error-message {
    color: #dc3545;
    font-size: 12px;
    display: none;
  }
  .error-message.visible {
    display: block;
  }
</style>

<script>
  // 防抖验证
  function debounce(fn, delay) {
    let timer;
    return function(...args) {
      clearTimeout(timer);
      timer = setTimeout(() => fn.apply(this, args), delay);
    };
  }
  
  const emailInput = document.getElementById('email');
  const errorMsg = emailInput.nextElementSibling;
  
  const validateEmail = debounce((value) => {
    const regex = /^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$/i;
    if (value && !regex.test(value)) {
      errorMsg.textContent = '请输入有效的邮箱地址';
      errorMsg.classList.add('visible');
      emailInput.setAttribute('aria-invalid', 'true');
      emailInput.setAttribute('aria-describedby', 'email-error');
    } else {
      errorMsg.textContent = '';
      errorMsg.classList.remove('visible');
      emailInput.setAttribute('aria-invalid', 'false');
    }
  }, 300);
  
  emailInput.addEventListener('input', (e) => validateEmail(e.target.value));
</script>

29. 无障碍(A11Y):缺少 ARIA 标签或键盘导航

问题描述

  • 自定义组件缺少 ARIA 属性,屏幕阅读器无法正确解读
  • 无法通过键盘操作自定义交互元素

解决方案

html 复制代码
<!-- 自定义下拉菜单的无障碍实现 -->
<div class="custom-dropdown">
  <button 
    type="button"
    aria-haspopup="listbox"
    aria-expanded="false"
    aria-controls="dropdown-list"
    id="dropdown-trigger"
  >
    选择选项
  </button>
  <ul 
    id="dropdown-list"
    role="listbox"
    aria-labelledby="dropdown-trigger"
    hidden
  >
    <li role="option" aria-selected="false" tabindex="-1">选项1</li>
    <li role="option" aria-selected="false" tabindex="-1">选项2</li>
    <li role="option" aria-selected="false" tabindex="-1">选项3</li>
  </ul>
</div>

<script>
  const trigger = document.getElementById('dropdown-trigger');
  const list = document.getElementById('dropdown-list');
  
  trigger.addEventListener('click', () => {
    const isExpanded = trigger.getAttribute('aria-expanded') === 'true';
    trigger.setAttribute('aria-expanded', !isExpanded);
    list.hidden = isExpanded;
  });
  
  // 键盘导航
  trigger.addEventListener('keydown', (e) => {
    if (e.key === 'ArrowDown' || e.key === 'ArrowUp') {
      e.preventDefault();
      trigger.click();
    }
  });
</script>

30. SEO 不友好:SPA 未使用 SSR(如 Next.js)

问题描述: 单页应用(SPA)初始加载时只有空的 HTML 结构,内容通过 JavaScript 动态渲染,搜索引擎爬虫可能无法正确索引内容。

解决方案

html 复制代码
<!-- 方案1:服务端渲染(SSR) -->
<!-- 使用 Next.js、Nuxt.js 等框架 -->
<!-- 服务器直接返回完整 HTML -->

<!-- 方案2:预渲染(Pre-rendering) -->
<!-- 构建时生成静态 HTML -->

<!-- 方案3:动态渲染 -->
<!-- 对爬虫返回服务端渲染内容,对用户返回 SPA -->

<!-- 方案4:使用 History API 而非 Hash 路由 -->
<!-- 坏:#/about -->
<!-- 好:/about -->

Next.js SSR 示例

jsx 复制代码
// pages/index.js (Next.js)
export async function getServerSideProps() {
  const data = await fetch('https://api.example.com/data');
  return { props: { data } };
}

export default function Home({ data }) {
  return (
    <div>
      <h1>{data.title}</h1>
      <p>{data.content}</p>
    </div>
  );
}
相关推荐
华夏之光永存1 小时前
独家:国家级光刻机项目架构师面试对话实录
面试·职场和发展
冬天vs不冷1 小时前
面试必知必会(14):MySQL执行计划与SQL优化
sql·mysql·面试
草莓熊Lotso1 小时前
《告别 “会用不会讲”:C++ string 底层原理拆解 + 手撕实现,面试 / 开发都适用》
开发语言·c++·面试
KNeeg_1 小时前
黑马点评完整代码(RabbitMQ优化)+简历编写+面试重点 ⭐
java·redis·后端·spring·面试·职场和发展·黑马点评
FPGA小迷弟1 小时前
FPGA工程师常见面试问题,有参考答案,必学!!!
fpga开发·面试·职场和发展·verilog·fpga·modelsim
Java后端的Ai之路1 小时前
以为AI开发就是调接口?一场25K的面试让我看到真相,原来真正的技术深度在这!
人工智能·面试·职场和发展·agent·ai应用开发
「已注销」1 小时前
面试分享:二本靠7轮面试成功拿下大厂P6
前端·javascript·面试
萧曵 丶1 小时前
MySQL 高频面试题(由浅到深 完整版,面试必背)
数据库·mysql·面试
醉颜凉1 小时前
超详细图解:HTTPS 中的 SSL/TLS 完整握手过程(面试必背)
面试·https·ssl
Lee川1 小时前
深入浅出:用 React 打造高性能懒加载无限滚动组件
前端·react.js