HTML 面试题

#前端#HTML

前端面试题 - HTML篇

本文档系统整理了前端面试中HTML相关的核心知识点,涵盖HTML5新特性、DOM操作、表单验证、可访问性、SEO、性能优化等多个维度。


📋 文档说明

面试中HTML的重要性

HTML作为前端开发的三大基石之一,在面试中占据重要地位:

  • 基础能力考察:体现候选人对Web标准的理解程度
  • 工程化思维:通过语义化、可访问性等考察代码质量意识
  • 性能优化视角:DOM操作、资源加载优化是高级面试必考点
  • 综合素养评估:SEO、兼容性处理体现项目经验

题目统计

统计项数量
总题数50道
基础题15道 (30%)
中级题25道 (50%)
高级题10道 (20%)

难度标识说明

  • 基础:HTML基础概念,适合初级面试
  • ⭐⭐ 中级:需要理解原理,适合1-3年经验
  • ⭐⭐⭐ 高级:综合应用和优化,适合3年以上经验

目录


一、HTML5新特性

1.1 语义化标签


1. 什么是HTML语义化?为什么要使用语义化标签?

难度:⭐(基础)
标签#语义化 #HTML5 #最佳实践

问题描述
请解释HTML语义化的概念,并说明在实际开发中使用语义化标签的好处。

参考答案要点

  • 语义化是指使用恰当的HTML标签来展示内容结构,让标签具有明确的含义
  • 主要好处:
    • 可读性:提高代码可读性和可维护性,便于团队协作
    • SEO优化:搜索引擎更容易理解页面结构和内容重要性
    • 可访问性:屏幕阅读器能正确解析页面,帮助视障用户
    • 开发效率:结构清晰,便于后期维护和迭代

2. HTML5新增了哪些语义化标签?请举例说明

难度:⭐(基础)
标签#HTML5 #语义化标签

问题描述
列举HTML5新增的语义化标签,并说明每个标签的适用场景。

参考答案要点

  • <header>:定义页面或区块的头部,通常包含logo、导航等
  • <nav>:定义导航链接区域
  • <article>:定义独立的文章内容,可独立分发
  • <section>:定义文档中的节或区块,有主题的内容分组
  • <aside>:定义侧边栏内容,与主内容相关的辅助信息
  • <footer>:定义页面或区块的底部
  • <main>:定义文档的主要内容(每个页面只有一个)
  • <figure>/<figcaption>:定义图文组合及标题
  • <time>:定义日期/时间
  • <mark>:定义高亮文本

代码示例

HTML
<body>
  <header>
    <h1>网站标题</h1>
    <nav>
      <a href="/">首页</a>
      <a href="/about">关于</a>
    </nav>
  </header>

  <main>
    <article>
      <header>
        <h2>文章标题</h2>
        <time datetime="2024-01-01">2024年1月1日</time>
      </header>
      <section>
        <p>文章内容...</p>
      </section>
    </article>

    <aside>
      <h3>相关推荐</h3>
      <ul>
        ...
      </ul>
    </aside>
  </main>

  <footer>
    <p>&copy; 2024 版权所有</p>
  </footer>
</body>

3. HTML5与HTML4的主要区别是什么?

难度:⭐⭐(中级)
标签#HTML5 #HTML4 #对比

问题描述
对比HTML5和HTML4,说明HTML5带来的主要改进和新增特性。

参考答案要点

特性HTML4HTML5
DOCTYPE复杂冗长<!DOCTYPE html>
语义化主要用div新增header、nav、article等
多媒体依赖Flash原生audio、video标签
表单类型有限email、date、number等
存储CookielocalStorage、sessionStorage
绘图不支持Canvas、SVG
API有限Geolocation、Web Workers等

4. 如何处理HTML5新标签的浏览器兼容问题(IE8及以下)?

难度:⭐⭐(中级)
标签#兼容性 #HTML5 #IE

问题描述
IE8及以下浏览器不支持HTML5新标签,如何解决这个问题?

参考答案要点

  1. 使用html5shiv库:最流行的解决方案
  2. 手动创建元素document.createElement('header')
  3. 添加默认样式:新标签需要设置为块级元素

代码示例

HTML
<!--[if lt IE 9]>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.min.js"></script>
<![endif]-->

<style>
  /* 确保新标签在旧IE中显示为块级元素 */
  article,
  aside,
  details,
  figcaption,
  figure,
  footer,
  header,
  hgroup,
  menu,
  nav,
  section {
    display: block;
  }
</style>

1.2 Canvas与SVG


5. Canvas和SVG有什么区别?

难度:⭐⭐(中级)
标签#Canvas #SVG #图形

问题描述
对比Canvas和SVG两种图形技术,说明它们的区别和适用场景。

参考答案要点

特性CanvasSVG
绘制方式基于像素的位图基于矢量的XML
缩放放大会失真缩放不失真
事件处理需要手动计算坐标每个元素可独立绑定事件
适用场景游戏、图像处理、像素操作图标、图表、Logo
性能适合大量图形渲染适合少量复杂图形
SEO不可搜索文本可搜索

6. Canvas的基本使用方法是什么?

难度:⭐⭐(中级)
标签#Canvas #绘图

问题描述
请演示Canvas的基本使用流程,包括获取上下文和绘制简单图形。

参考答案要点

  • 通过getContext('2d')获取2D渲染上下文
  • 支持绘制矩形、路径、文本、图像等
  • 支持变换、渐变、阴影等效果

代码示例

HTML
<canvas id="myCanvas" width="500" height="300"></canvas>

<script>
  var canvas = document.getElementById("myCanvas")
  var ctx = canvas.getContext("2d")

  // 绘制矩形
  ctx.fillStyle = "green"
  ctx.fillRect(10, 10, 150, 50)

  // 绘制圆形
  ctx.beginPath()
  ctx.arc(250, 150, 50, 0, 2 * Math.PI)
  ctx.fillStyle = "blue"
  ctx.fill()

  // 绘制文本
  ctx.font = "20px Arial"
  ctx.fillStyle = "black"
  ctx.fillText("Hello Canvas", 10, 100)
</script>

1.3 本地存储


7. localStorage、sessionStorage和Cookie的区别?

难度:⭐(基础)
标签#存储 #localStorage #Cookie

问题描述
对比三种客户端存储方式的特点和适用场景。

参考答案要点

特性localStoragesessionStorageCookie
生命周期永久(手动清除)页面关闭清除可设置过期时间
存储大小~5-10MB~5-10MB~4KB
与服务端通信不自动发送不自动发送每次请求自动携带
作用域同源同源+同标签页可设置domain/path
适用场景用户偏好设置、主题临时表单数据登录状态Token

代码示例

JAVASCRIPT
// localStorage
localStorage.setItem("username", "张三")
localStorage.getItem("username")
localStorage.removeItem("username")
localStorage.clear()

// sessionStorage
sessionStorage.setItem("tempData", "临时数据")

// Cookie
document.cookie = "name=value; expires=Thu, 18 Dec 2024 12:00:00 UTC; path=/"

8. 为什么sessionStorage在不同Tab页之间不共享?

难度:⭐⭐(中级)
标签#sessionStorage #浏览器原理

问题描述
解释sessionStorage的隔离机制,以及为什么设计成这样。

参考答案要点

  • 这是W3C标准的刻意设计,核心原则是隔离而非共享
  • 每个Tab/Window有独立的顶级浏览上下文
  • sessionStorage的设计初衷是存储会话级别的临时数据
  • 特殊情况:通过window.open或链接打开新页面时,新页面会复制原页面的sessionStorage

9. localStorage的storage事件是什么?如何使用?

难度:⭐⭐(中级)
标签#localStorage #事件 #跨标签页通信

问题描述
解释storage事件的作用和使用场景,并给出代码示例。

参考答案要点

  • 其他标签页修改localStorage时触发
  • 可用于跨标签页通信
  • 重要特性:当前页面修改不会触发,只有其他页面修改才会触发

代码示例

JAVASCRIPT
// 监听storage事件
window.addEventListener("storage", (e) => {
  console.log("变化的key:", e.key)
  console.log("旧值:", e.oldValue)
  console.log("新值:", e.newValue)
  console.log("发生变化的页面URL:", e.url)
  console.log("存储区域:", e.storageArea)
})

// 应用场景:一个标签页登录,其他标签页同步登录状态

1.4 Web Workers与Service Workers


10. Web Worker的作用是什么?如何使用?

难度:⭐⭐⭐(高级)
标签#WebWorker #多线程 #性能

问题描述
解释Web Worker的作用,并说明使用方法和限制。

参考答案要点

  • 作用:在后台线程中运行JavaScript,不阻塞主线程
  • 适用场景:复杂计算、大数据处理、图像处理等耗时操作
  • 重要限制:无法访问DOM,不能操作页面元素

代码示例

JAVASCRIPT
// main.js - 主线程
// 创建Worker
var worker = new Worker("worker.js")

// 发送数据到Worker
worker.postMessage({ numbers: [1, 2, 3, 4, 5] })

// 接收Worker返回的数据
worker.onmessage = function (e) {
  console.log("计算结果:", e.data)
}

// 处理错误
worker.onerror = function (error) {
  console.error("Worker错误:", error)
}

// 终止Worker
worker.terminate()
JAVASCRIPT
// worker.js - Worker线程
self.onmessage = function (e) {
  var numbers = e.data.numbers
  var result = numbers.reduce((a, b) => a + b, 0)

  // 将结果发送回主线程
  self.postMessage(result)
}

11. Service Worker是什么?有什么应用场景?

难度:⭐⭐⭐(高级)
标签#ServiceWorker #PWA #离线缓存

问题描述
解释Service Worker的概念、特点,并列举典型应用场景。

参考答案要点

  • 定义:一种特殊的Web Worker,充当Web应用与浏览器之间的代理服务器
  • 核心特点
    • 独立于主线程运行
    • 拦截网络请求
    • 支持离线缓存
    • 支持推送通知
  • 应用场景
    • PWA(渐进式Web应用)
    • 离线访问
    • 后台同步
    • 推送通知

12. HTML5离线存储(Application Cache)如何使用?

难度:⭐⭐(中级)
标签#离线存储 #AppCache

问题描述
说明Application Cache的使用方法和manifest文件结构。

参考答案要点

  • 在html标签添加manifest属性
  • manifest文件包含CACHE、NETWORK、FALLBACK三个部分
  • 注意:AppCache已被废弃,推荐使用Service Workers

代码示例

HTML
<html manifest="demo.appcache"></html>
Plain Text
CACHE MANIFEST
# 版本号:v1.0

CACHE:
js/app.js
css/style.css
images/logo.png

NETWORK:
*
api/

FALLBACK:
/ /offline.html

1.5 多媒体与API


13. HTML5的video和audio标签有哪些常用属性?

难度:⭐(基础)
标签#多媒体 #video #audio

问题描述
列举video和audio标签的常用属性及其作用。

参考答案要点

属性作用
controls显示播放控件(播放、暂停、音量等)
autoplay自动播放
loop循环播放
muted静音
preload预加载策略(auto/metadata/none)
poster视频封面图(video专用)
width/height设置播放器尺寸

代码示例

HTML
<!-- 视频 -->
<video controls width="640" height="360" poster="cover.jpg">
  <source src="video.mp4" type="video/mp4" />
  <source src="video.webm" type="video/webm" />
  您的浏览器不支持视频播放。
</video>

<!-- 音频 -->
<audio controls preload="metadata">
  <source src="audio.mp3" type="audio/mpeg" />
  <source src="audio.ogg" type="audio/ogg" />
  您的浏览器不支持音频播放。
</audio>

14. Web Components包含哪些核心技术?

难度:⭐⭐⭐(高级)
标签#WebComponents #组件化 #自定义元素

问题描述
介绍Web Components的四大核心技术,并给出简单示例。

参考答案要点

  1. Custom Elements:定义自定义HTML元素
  2. Shadow DOM:封装组件内部结构和样式,实现隔离
  3. HTML Templates:定义可复用的HTML模板
  4. Slots:创建可插入内容的占位符

代码示例

JAVASCRIPT
// 定义自定义元素
class MyComponent extends HTMLElement {
  constructor() {
    super()

    // 创建Shadow DOM
    this.attachShadow({ mode: "open" })

    // 定义模板
    this.shadowRoot.innerHTML = `
      <style>
        div { color: blue; padding: 10px; }
      </style>
      <div>自定义组件内容</div>
      <slot></slot>
    `
  }

  connectedCallback() {
    console.log("组件被添加到DOM")
  }
}

// 注册自定义元素
customElements.define("my-component", MyComponent)
HTML
<!-- 使用自定义元素 -->
<my-component>
  <p>这是slot插入的内容</p>
</my-component>

二、DOM操作和事件机制

2.1 事件基础


15. 什么是事件冒泡和事件捕获?

难度:⭐(基础)
标签#事件 #冒泡 #捕获

问题描述
解释事件冒泡和事件捕获的概念,以及DOM标准事件流的执行顺序。

参考答案要点

  • 事件捕获(Capture Phase):从document → parent → child(从外到内)
  • 事件冒泡(Bubble Phase):从child → parent → document(从内到外)
  • DOM标准事件流:先捕获再冒泡
  • addEventListener第三个参数
    • false(默认):事件冒泡阶段触发
    • true:事件捕获阶段触发

代码示例

JAVASCRIPT
// 事件捕获
parent.addEventListener(
  "click",
  function () {
    console.log("parent - 捕获")
  },
  true
)

// 事件冒泡(默认)
child.addEventListener(
  "click",
  function () {
    console.log("child - 冒泡")
  },
  false
)

// 点击child时输出顺序:
// 1. parent - 捕获
// 2. child - 冒泡

16. 如何阻止事件冒泡和默认事件?

难度:⭐(基础)
标签#事件 #兼容性

问题描述
编写兼容各浏览器的代码,实现阻止事件冒泡和阻止默认事件。

参考答案要点

  • stopPropagation():阻止事件冒泡
  • preventDefault():阻止默认事件
  • 需要考虑IE兼容性

代码示例

JAVASCRIPT
// 阻止事件冒泡
function stopBubble(e) {
  if (e && e.stopPropagation) {
    e.stopPropagation() // 标准浏览器
  } else {
    window.event.cancelBubble = true // IE兼容
  }
}

// 阻止默认事件
function stopDefault(e) {
  if (e && e.preventDefault) {
    e.preventDefault() // 标准浏览器
  } else {
    window.event.returnValue = false // IE兼容
  }
}

// 使用示例
element.addEventListener("click", function (e) {
  stopBubble(e)
  stopDefault(e)
})

17. 所有事件都有冒泡吗?哪些事件不冒泡?

难度:⭐⭐(中级)
标签#事件 #冒泡

问题描述
列举不冒泡的事件类型,并解释原因。

参考答案要点不是所有事件都有冒泡,以下事件不冒泡:

  • blur:元素失去焦点
  • focus:元素获得焦点
  • mouseenter:鼠标进入元素
  • mouseleave:鼠标离开元素
  • load:资源加载完成
  • unload:页面卸载
  • resize:窗口大小改变
  • scroll:滚动

原因:这些事件的设计初衷是关注元素自身的状态变化,不涉及父子元素间的交互传播。


2.2 事件委托


18. 什么是事件委托?有什么优缺点?

难度:⭐⭐(中级)
标签#事件委托 #性能优化

问题描述
解释事件委托的原理,分析其优缺点。

参考答案要点

  • 原理:利用事件冒泡,将事件处理程序绑定到父元素而非每个子元素
  • 优点
    • 减少内存消耗,节省事件注册数量
    • 动态添加的元素自动拥有事件处理
    • 减少DOM操作,提高性能
  • 缺点
    • 基于冒泡,不冒泡的事件无法委托
    • 层级过多可能影响性能
    • 可能出现事件误判(需要判断target)

19. 实现一个事件委托函数

难度:⭐⭐(中级)
标签#事件委托 #代码实现

问题描述
编写一个通用的事件委托函数。

参考答案要点

  • 使用事件冒泡机制
  • 判断事件源是否匹配目标元素类型
  • 使用call绑定this指向

代码示例

JAVASCRIPT
/**
 * 事件委托函数
 * @param {Element} parent - 父元素
 * @param {string} childSelector - 子元素选择器
 * @param {string} eventType - 事件类型
 * @param {Function} callback - 回调函数
 */
function delegate(parent, childSelector, eventType, callback) {
  parent.addEventListener(eventType, function (e) {
    var target = e.target

    // 向上查找匹配的元素
    while (target !== parent) {
      if (target.matches(childSelector)) {
        callback.call(target, e)
        return
      }
      target = target.parentNode
    }
  })
}

// 使用示例
delegate(document.getElementById("list"), "li", "click", function (e) {
  console.log("点击了:", this.innerHTML)
})

20. e.target和e.currentTarget的区别?

难度:⭐⭐(中级)
标签#事件 #DOM

问题描述
解释事件对象中target和currentTarget的区别。

参考答案要点

属性含义
e.target触发事件的实际元素(事件源)
e.currentTarget绑定事件处理程序的元素
  • 在事件委托中:
    • target是被点击的具体子元素
    • currentTarget是绑定了事件的父元素

代码示例

JAVASCRIPT
document.getElementById("list").addEventListener("click", function (e) {
  console.log("target:", e.target) // 被点击的li
  console.log("currentTarget:", e.currentTarget) // 绑定了事件的ul#list
})

2.3 DOM操作


21. DocumentFragment是什么?与直接操作DOM的区别?

难度:⭐⭐(中级)
标签#DOM #性能优化 #DocumentFragment

问题描述
解释DocumentFragment的作用和优势。

参考答案要点

  • DocumentFragment是轻量级的虚拟DOM容器
  • 特点
    • 没有父节点,不会被渲染到页面上
    • 不会影响页面的回流和重绘
  • 优势:批量DOM操作时,先在内存中操作,最后一次性添加到DOM树,只触发一次渲染

代码示例

JAVASCRIPT
// 低效方式 - 每次appendChild都触发回流
for (var i = 0; i < 1000; i++) {
  var li = document.createElement("li")
  document.getElementById("list").appendChild(li) // 1000次回流!
}

// 高效方式 - 使用DocumentFragment
var fragment = document.createDocumentFragment()
for (var i = 0; i < 1000; i++) {
  var li = document.createElement("li")
  fragment.appendChild(li) // 内存操作,不触发回流
}
document.getElementById("list").appendChild(fragment) // 只触发1次回流

22. 如何高效地操作大量DOM元素?

难度:⭐⭐⭐(高级)
标签#DOM #性能优化 #大数据

问题描述
列举优化大量DOM元素操作的方法。

参考答案要点

  1. 使用DocumentFragment批量操作
  2. 使用requestAnimationFrame分批渲染,避免阻塞
  3. 使用虚拟DOM(React/Vue等框架)
  4. 使用innerHTML代替多次appendChild
  5. 先隐藏元素再操作,操作完成后再显示
  6. 缓存DOM查询结果,避免重复查询
  7. 使用虚拟列表(只渲染可视区域)
  8. 防抖/节流控制操作频率

三、表单和验证

3.1 HTML5表单增强


23. HTML5新增了哪些表单输入类型?

难度:⭐(基础)
标签#表单 #HTML5 #输入类型

问题描述
列举HTML5新增的表单输入类型。

参考答案要点

类型说明
email邮箱地址,自动验证格式
tel电话号码
urlURL地址
number数字,可设置min/max/step
range滑块范围选择器
date日期选择器
time时间选择器
datetime-local本地日期时间
color颜色选择器
search搜索框
month/week月份/周选择器

代码示例

HTML
<input type="email" placeholder="请输入邮箱" />
<input type="number" min="0" max="100" step="5" />
<input type="date" min="2024-01-01" max="2024-12-31" />
<input type="color" value="#ff0000" />
<input type="range" min="0" max="100" value="50" />

24. HTML5表单有哪些新的属性?

难度:⭐(基础)
标签#表单 #HTML5

问题描述
列举HTML5表单的新增属性。

参考答案要点

属性作用
placeholder输入提示文本
required必填验证
pattern正则表达式验证
min/max数值范围限制
step数值间隔
autofocus自动聚焦
autocomplete自动完成(on/off)
multiple允许多选(file/email)
novalidate关闭表单验证
form关联外部表单

3.2 表单验证


25. HTML5表单验证的API有哪些?

难度:⭐⭐(中级)
标签#表单验证 #API

问题描述
介绍HTML5表单验证的相关API。

参考答案要点属性:

  • validationMessage:验证失败时的提示信息
  • validity:验证状态对象
  • willValidate:是否会被验证

validity对象属性:

  • valid:验证是否通过
  • valueMissing:required验证失败
  • typeMismatch:类型不匹配
  • patternMismatch:pattern验证失败
  • tooLong/tooShort:长度验证失败
  • rangeOverflow/rangeUnderflow:范围验证失败

方法:

  • checkValidity():执行验证并返回结果
  • setCustomValidity(message):设置自定义错误信息

26. 如何实现自定义表单验证?

难度:⭐⭐(中级)
标签#表单验证 #自定义验证

问题描述
编写代码实现自定义表单验证。

参考答案要点

  • 使用setCustomValidity()设置自定义错误信息
  • 使用checkValidity()检查验证状态
  • 结合input事件实时验证

代码示例

JAVASCRIPT
// 自定义验证 - 用户名长度
var input = document.getElementById("username")
input.addEventListener("input", function () {
  if (this.value.length < 3) {
    this.setCustomValidity("用户名至少3个字符")
  } else if (this.value.length > 20) {
    this.setCustomValidity("用户名最多20个字符")
  } else {
    this.setCustomValidity("") // 清空错误信息
  }
})

// 表单提交时验证
form.addEventListener("submit", function (e) {
  if (!this.checkValidity()) {
    e.preventDefault()
    // 处理验证失败
    console.log("表单验证失败")
  }
})

27. 表单验证的伪类有哪些?

难度:⭐⭐(中级)
标签#CSS #表单验证 #伪类

问题描述
列举与表单验证相关的CSS伪类。

参考答案要点

伪类说明
:valid验证通过
:invalid验证失败
:required必填字段
:optional可选字段
:in-range在范围内
:out-of-range超出范围
:read-only只读
:read-write可读写
:checked已选中(radio/checkbox)

代码示例

CSS
/* 验证通过的样式 */
input:valid {
  border-color: green;
}

/* 验证失败的样式 */
input:invalid {
  border-color: red;
}

/* 必填字段 */
input:required {
  background-color: #fffacd;
}

四、可访问性(Accessibility/A11y)

4.1 基础概念


28. 什么是Web可访问性(A11y)?

难度:⭐(基础)
标签#可访问性 #A11y #无障碍

问题描述
解释Web可访问性的概念和重要性。

参考答案要点

  • 可访问性(Accessibility,缩写a11y)是指确保网页内容能够被所有人平等获取和使用
  • 目标用户
    • 视障人士(使用屏幕阅读器)
    • 听障人士
    • 运动障碍人士
    • 认知障碍人士
  • 好处
    • 提升用户体验
    • 符合法律要求(如WCAG标准)
    • 扩大用户群体
    • 有利于SEO

29. alt属性和title属性的区别?

难度:⭐(基础)
标签#可访问性 #SEO #图片

问题描述
对比img标签的alt和title属性的区别。

参考答案要点

属性alttitle
作用图片无法显示时的替代文本鼠标悬停时的提示信息
SEO重要,搜索引擎可识别影响较小
可访问性屏幕阅读器读取部分屏幕阅读器支持
使用场景所有图片都应有可选,提供额外说明

代码示例

HTML
<img src="photo.jpg" alt="一只橘色的猫在阳光下睡觉" title="点击放大查看" />

4.2 ARIA


30. 什么是ARIA?常见的ARIA属性有哪些?

难度:⭐⭐(中级)
标签#ARIA #可访问性 #无障碍

问题描述
介绍ARIA的概念和常用属性。

参考答案要点

  • ARIA(Accessible Rich Internet Applications)是一组属性,用于增强Web内容和应用的可访问性
  • 当HTML语义化不足时,ARIA可以补充说明元素的角色、状态和属性

常见属性

属性作用
role定义元素角色(navigation、main、button等)
aria-label为元素提供标签
aria-labelledby引用其他元素作为标签
aria-describedby提供额外描述
aria-hidden隐藏元素不被屏幕阅读器读取
aria-expanded展开/折叠状态
aria-checked选中状态
aria-disabled禁用状态

代码示例

HTML
<!-- 自定义按钮 -->
<div role="button" tabindex="0" aria-label="关闭对话框" aria-pressed="false">
  X
</div>

<!-- 导航 -->
<nav role="navigation" aria-label="主导航">
  <ul>
    ...
  </ul>
</nav>

31. 如何隐藏内容但对屏幕阅读器可见?

难度:⭐⭐(中级)
标签#可访问性 #CSS #屏幕阅读器

问题描述
实现一种CSS方案,让内容视觉上隐藏但对屏幕阅读器可见。

参考答案要点

  • display: nonevisibility: hidden不同
  • 该方法隐藏视觉但保留在可访问树中
  • 常用于为图标按钮添加文字说明

代码示例

CSS
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
HTML
<button>
  <span class="visually-hidden">搜索</span>
  <i class="icon-search"></i>
</button>

4.3 键盘导航


32. 如何确保网站支持键盘导航?

难度:⭐⭐(中级)
标签#可访问性 #键盘导航 #无障碍

问题描述
列举确保网站支持键盘导航的要点。

参考答案要点

  • 确保所有交互元素可通过Tab键访问
  • 合理的Tab顺序(使用tabindex,推荐值为0或-1)
  • 提供可见的焦点指示器(focus样式)
  • 支持Enter/Space激活按钮和链接
  • 支持Esc关闭弹窗和菜单
  • 避免键盘陷阱(用户无法通过Tab离开某个区域)
  • 提供跳过链接(Skip Link)快速到达主内容

代码示例

CSS
/* 可见的焦点样式 */
:focus {
  outline: 2px solid #007bff;
  outline-offset: 2px;
}

/* 不要完全移除outline */
:focus:not(:focus-visible) {
  outline: none;
}

五、SEO优化

5.1 基础优化


33. 前端如何实现SEO优化?

难度:⭐⭐(中级)
标签#SEO #优化 #前端

问题描述
从前端角度说明SEO优化的方法。

参考答案要点内部优化:

  • TDK优化:Title、Keywords、Description
  • 语义化HTML标签
  • 合理的heading层级(h1-h6表示标题层级)
  • 图片alt属性
  • 内部链接优化
  • 网站内容更新
  • 服务器端渲染(SSR)

外部优化:

  • 外部链接建设
  • 友情链接交换
  • 社交媒体推广

34. meta标签对SEO有什么作用?

难度:⭐(基础)
标签#SEO #meta #HTML

问题描述
列举常用的meta标签及其SEO作用。

参考答案要点

代码示例

HTML
<!-- 字符编码 -->
<meta charset="UTF-8" />

<!-- 视口设置(移动端必备) -->
<meta name="viewport" content="width=device-width, initial-scale=1.0" />

<!-- 页面描述(搜索结果展示) -->
<meta name="description" content="页面描述内容,150字以内" />

<!-- 关键词(现代搜索引擎权重降低) -->
<meta name="keywords" content="关键词1, 关键词2" />

<!-- 作者 -->
<meta name="author" content="作者名" />

<!-- 禁止搜索引擎索引 -->
<meta name="robots" content="noindex, nofollow" />

<!-- Open Graph(社交媒体分享) -->
<meta property="og:title" content="标题" />
<meta property="og:description" content="描述" />
<meta property="og:image" content="分享图片URL" />

35. 什么是语义化HTML对SEO的影响?

难度:⭐⭐(中级)
标签#SEO #语义化

问题描述
说明语义化HTML对SEO的影响。

参考答案要点

  • 帮助搜索引擎理解页面结构和内容重要性
  • 重要的内容使用合适的标签(h1-h6表示标题层级)
  • 使用nav、article、section等标签明确内容区域
  • 提高页面在搜索结果中的展示效果
  • 有助于富媒体摘要(Rich Snippets)的生成
  • 提升页面在搜索结果中的排名

5.2 结构化数据


36. 什么是结构化数据?如何实现?

难度:⭐⭐⭐(高级)
标签#SEO #结构化数据 #Schema

问题描述
解释结构化数据的概念和实现方式。

参考答案要点

  • 结构化数据是一种标准化格式,用于向搜索引擎提供页面内容的详细信息
  • 实现方式
    • JSON-LD(推荐,Google首选)
    • Microdata
    • RDFa
  • 常用Schema类型
    • Article(文章)
    • Product(产品)
    • Organization(组织)
    • Person(人物)
    • BreadcrumbList(面包屑)

代码示例

HTML
<script type="application/ld+json">
  {
    "@context": "https://schema.org",
    "@type": "Article",
    "headline": "文章标题",
    "author": {
      "@type": "Person",
      "name": "作者名"
    },
    "datePublished": "2024-01-01",
    "publisher": {
      "@type": "Organization",
      "name": "出版社"
    }
  }
</script>

六、性能优化

6.1 资源加载优化


37. preload和prefetch的区别?

难度:⭐⭐(中级)
标签#性能优化 #资源加载 #preload

问题描述
对比preload和prefetch的区别和使用场景。

参考答案要点

特性preloadprefetch
目的立即加载当前页面关键资源提前加载将来可能需要的资源
优先级高优先级低优先级(空闲时加载)
使用场景首屏CSS/JS/字体下一页资源
对当前页面直接影响加载速度不直接影响

代码示例

HTML
<!-- preload - 预加载关键资源 -->
<link rel="preload" href="/styles/main.css" as="style" />
<link rel="preload" href="/scripts/app.js" as="script" />
<link
  rel="preload"
  href="/fonts/font.woff2"
  as="font"
  type="font/woff2"
  crossorigin
/>

<!-- prefetch - 预加载下一页资源 -->
<link rel="prefetch" href="/scripts/nextpage.js" />
<link rel="prefetch" href="/styles/nextpage.css" />

<!-- preconnect - 预连接DNS -->
<link rel="preconnect" href="https://cdn.example.com" />

38. 什么是懒加载?如何实现图片懒加载?

难度:⭐⭐(中级)
标签#性能优化 #懒加载 #图片

问题描述
解释懒加载的概念,并给出图片懒加载的实现方案。

参考答案要点

  • 概念:延迟加载页面资源,只在需要时(如进入视口)加载
  • 好处:减少首屏加载时间、节省带宽

代码示例

JAVASCRIPT
// 方式1 - Intersection Observer API(推荐)
const images = document.querySelectorAll("img[data-src]")

const observer = new IntersectionObserver((entries) => {
  entries.forEach((entry) => {
    if (entry.isIntersecting) {
      const img = entry.target
      img.src = img.dataset.src
      img.removeAttribute("data-src")
      observer.unobserve(img)
    }
  })
})

images.forEach((img) => observer.observe(img))
HTML
<!-- 方式2 - 原生懒加载(现代浏览器支持) -->
<img src="placeholder.jpg" data-src="real.jpg" loading="lazy" alt="描述" />

39. 懒加载和预加载的区别?

难度:⭐(基础)
标签#性能优化 #加载策略

问题描述
对比懒加载和预加载的区别。

参考答案要点

特性懒加载预加载
加载时机按需加载,延迟加载提前加载
目的减少首屏加载时间提升后续访问速度
适用场景非关键资源(图片、视频)关键资源、下一页资源
带宽影响节省带宽消耗额外带宽

6.2 渲染优化


40. 什么是回流(Reflow)和重绘(Repaint)?

难度:⭐⭐(中级)
标签#性能优化 #渲染 #回流重绘

问题描述
解释回流和重绘的概念,以及它们的区别。

参考答案要点

  • 回流(Reflow/重排)
    • 重新计算元素的几何属性(位置、大小)
    • 触发条件:元素尺寸变化、DOM结构变化、窗口大小变化
    • 性能开销
  • 重绘(Repaint)
    • 重新绘制元素外观(颜色、背景等)
    • 不影响布局
    • 性能开销相对较小
  • 关系:回流一定会触发重绘,重绘不一定会触发回流

41. 如何避免回流和重绘?

难度:⭐⭐⭐(高级)
标签#性能优化 #渲染 #最佳实践

问题描述
列举避免回流和重绘的方法。

参考答案要点

  1. 使用CSS Transform和Opacity进行动画(GPU加速)
  2. 批量修改样式(使用className切换,而非逐个修改style)
  3. 避免频繁读取布局属性(offsetWidth、clientHeight等)
  4. 使用DocumentFragment批量操作DOM
  5. 使用will-change属性创建新渲染层
  6. 使用requestAnimationFrame优化动画
  7. 避免使用table布局(table的回流成本高)
  8. 将元素脱离文档流后再进行复杂操作

42. 如何优化大量数据的渲染性能?

难度:⭐⭐⭐(高级)
标签#性能优化 #大数据 #渲染

问题描述
列举优化大量数据渲染性能的方法。

参考答案要点

  1. 虚拟列表:只渲染可视区域内的元素(如react-window、vue-virtual-scroller)
  2. 分页加载:分批次请求和渲染数据
  3. 时间分片:使用requestAnimationFrame分批渲染
  4. 骨架屏:提升感知性能
  5. 防抖节流:控制事件触发频率
  6. Web Workers:数据处理放到后台线程
  7. Object.freeze:冻结不需要响应式的数据

七、常见兼容性问题

7.1 浏览器差异


43. DOCTYPE的作用是什么?标准模式和怪异模式的区别?

难度:⭐(基础)
标签#DOCTYPE #兼容性 #渲染模式

问题描述
解释DOCTYPE的作用,以及标准模式和怪异模式的区别。

参考答案要点

  • DOCTYPE作用
    • 告诉浏览器文档类型和HTML版本
    • 决定浏览器的渲染模式
  • 标准模式
    • 严格遵循W3C标准
    • 使用W3C标准盒模型(width=content)
  • 怪异模式(Quirks Mode):
    • 模拟旧浏览器行为(主要是IE5.5)
    • 使用IE盒模型(width=content+padding+border)
  • HTML5 DOCTYPE<!DOCTYPE html>

44. 常见的事件兼容性处理有哪些?

难度:⭐⭐(中级)
标签#兼容性 #事件 #IE

问题描述
编写兼容各浏览器的事件处理代码。

参考答案要点

  • 获取事件对象
  • 获取事件源
  • 阻止冒泡和默认事件
  • 添加事件监听

代码示例

JAVASCRIPT
// 获取事件对象
var e = event || window.event

// 获取事件源
var target = e.target || e.srcElement

// 阻止冒泡
if (e.stopPropagation) {
  e.stopPropagation()
} else {
  e.cancelBubble = true
}

// 阻止默认事件
if (e.preventDefault) {
  e.preventDefault()
} else {
  e.returnValue = false
}

// 添加事件监听
if (element.addEventListener) {
  element.addEventListener("click", fn, false)
} else if (element.attachEvent) {
  element.attachEvent("onclick", fn)
} else {
  element.onclick = fn
}

45. IE浏览器有哪些常见的兼容性问题?

难度:⭐⭐(中级)
标签#兼容性 #IE

问题描述
列举IE浏览器的常见兼容性问题。

参考答案要点

  • IE6不支持PNG透明:使用滤镜或PNG8格式
  • IE盒模型差异:使用box-sizing: border-box
  • 获取兄弟元素:不支持previousElementSibling
  • 事件对象差异:使用window.event
  • CSS选择器支持有限:不支持高级选择器
  • 不支持ES6新特性:需要polyfill
  • Flex/Grid布局支持问题:IE10+部分支持Flex

7.2 移动端兼容


46. 移动端有哪些常见的HTML兼容性问题?

难度:⭐⭐(中级)
标签#移动端 #兼容性

问题描述
列举移动端常见的兼容性问题及解决方案。

参考答案要点

问题解决方案
点击延迟问题(300ms)使用fastclick库或touch事件
软键盘弹出影响布局使用viewport设置或fixed定位
1px边框问题使用transform缩放或伪元素
输入框聚焦问题调整scrollIntoView
日期选择器差异使用第三方组件(如picker)
视频自动播放限制需要用户交互触发
iOS橡皮筋效果使用-webkit-overflow-scrolling

八、综合题目


47. 从输入URL到页面显示发生了什么?

难度:⭐⭐⭐(高级)
标签#浏览器原理 #网络 #渲染

问题描述
详细描述从输入URL到页面完整显示的整个过程。

参考答案要点

  1. DNS解析:域名解析为IP地址
  2. TCP连接:三次握手建立连接
  3. 发送HTTP请求
  4. 服务器处理请求并返回响应
  5. 浏览器解析HTML构建DOM树
  6. 解析CSS构建CSSOM树
  7. 合并DOM和CSSOM构建渲染树
  8. 布局(Layout/Reflow)
  9. 绘制(Paint)
  10. 合成(Composite)

48. 如何优化首屏加载时间?

难度:⭐⭐⭐(高级)
标签#性能优化 #首屏加载 #FCP

问题描述
列举优化首屏加载时间的方法。

参考答案要点

  1. 减少HTTP请求(合并资源、使用雪碧图)
  2. 启用Gzip压缩
  3. 使用CDN
  4. 懒加载非关键资源
  5. 预加载关键资源(preload)
  6. 服务端渲染(SSR)
  7. 代码分割和按需加载
  8. 优化图片(压缩、WebP格式、响应式图片)
  9. 使用浏览器缓存
  10. 减少重定向
  11. 内联关键CSS
  12. 延迟加载非关键JavaScript

49. 什么是渐进增强和优雅降级?

难度:⭐⭐(中级)
标签#兼容性 #设计理念

问题描述
解释渐进增强和优雅降级的概念及区别。

参考答案要点

特性渐进增强优雅降级
思路从基本功能开始,逐步添加高级特性先构建完整功能,再处理兼容性问题
优先级优先保证基础功能可用高级浏览器获得完整体验
适用用户适用于所有用户旧浏览器获得基本体验
开发方式先写基础HTML,再增强先写完整功能,再写兼容代码

50. HTML5的拖拽API有哪些事件?

难度:⭐⭐(中级)
标签#HTML5 #拖拽 #API

问题描述
列举HTML5拖拽API的事件。

参考答案要点

事件触发时机
dragstart开始拖拽
drag拖拽中(持续触发)
dragenter进入目标元素
dragover在目标元素上移动(持续触发)
dragleave离开目标元素
drop在目标元素上释放
dragend拖拽结束

代码示例

JAVASCRIPT
var draggedElement = null

// 拖拽源
document
  .querySelector(".draggable")
  .addEventListener("dragstart", function (e) {
    draggedElement = this
    e.dataTransfer.effectAllowed = "move"
  })

// 放置目标
document.querySelector(".dropzone").addEventListener("dragover", function (e) {
  e.preventDefault() // 必须阻止默认行为才能drop
  e.dataTransfer.dropEffect = "move"
})

document.querySelector(".dropzone").addEventListener("drop", function (e) {
  e.preventDefault()
  this.appendChild(draggedElement)
})

复习建议与学习资源

📚 复习建议

  1. 按难度循序渐进

    • 初级开发者:重点掌握基础题(⭐)
    • 中级开发者:深入理解中级题(⭐⭐)
    • 高级开发者:攻克高级题(⭐⭐⭐)
  2. 重点题目推荐

    优先级题目原因
    🔥🔥🔥Q47(URL到页面显示)必考题,考察浏览器原理
    🔥🔥🔥Q48(首屏优化)性能优化核心
    🔥🔥Q15/Q16(事件机制)DOM基础
    🔥🔥Q7(存储对比)高频考点
    🔥🔥Q37(preload/prefetch)性能优化热点
  3. 学习方法

    • 理解原理 > 死记硬背
    • 动手实践 > 只看不做
    • 结合实际项目 > 孤立学习

🎯 面试技巧

  1. 回答要有条理:使用"首先...其次...最后"的结构
  2. 结合项目经验:理论+实践更有说服力
  3. 承认不知道:遇到不会的问题,诚实说明并表达学习意愿
  4. 主动扩展:回答完问题后,可以主动补充相关知识点

最后更新于: 2026-02-27

目录