2025 年前端高频面试题——HTML

200 阅读12分钟

HTML5 相比 HTML4 有哪些重大改进?列举至少5个新特性。

  • 标签上的改动

    • 新增了一些语义化标签,比如像: nav、footer、header、ssection之类的
    • 提供了一些新功能的标签:video、audio
    • 删除了一些标记表现,比如font
  • API新增

    • Canvas、Svg
    • 媒体播放器(video、audio)
    • 拖拽
    • indexedDB
    • 新增了一些表单元素:progress

什么是语义化标签?列举常见的语义化标签并说明其用途。

语义化标签,可以让开发者构建清晰的页面结构,同时也更有利于爬虫对网站内容的解析。

  • html文档结构清晰,比如header、section、footer的经典布局
  • 更好的用户体验,像img标签的alt属性,即使在图片未加载的情况下,可以显示图片信息。
  • 更有利于网站的SEO优化,爬虫解析依赖标签来决定上下文关键字的权重。

<!DOCTYPE html> 的作用是什么?如果不写会发生什么?

<!DOCTYPE html> 是HTML文档类型声明,它的作用是告诉浏览器按照最新的标准模式来保证 HTML文档。

如果不声明,可能会触发怪异模式。

  • CSS布局错乱(width和 padding的计算方式不同)
  • javascript行为错误

HTML 中的 data-* 属性有什么作用?如何通过 JavaScript 访问?

data-* 其实就是一个自定义的attribute,开发者用来存储html标签对应的数据,基本上只能存储字符串类型(当然序列化后的js对象也可以存)。也可以当成一个自定义属性来设置css内容(其实就是一个自定义的属性选择器)

js通过获取data-*

// 通过getAttribute 访问
let btn = document.querySelector('#btn')
let size = btn.getAttribute('data-size')
// 通过dataset访问
size = btn.dataset.size

css访问:

btn[data-size="sm"] {
  width:100px;
  height:32px;
  font-size:14px;
}

参考链接:

juejin.cn/post/684490…

<meta> 标签有哪些常见用法?(如 viewport、charset、SEO 相关)

<meta> 标签用于定义 HTML 文档的元数据(metadata),用来表示HTML文件的解析、SEO、移动端适配等内容。

  1. 字符编码声明
<meta charset="UTF-8">

2. 控制浏览器的布局和缩放

<meta name="viewport" content="width=device-width, initial-scale=1.0">

3. SEO相关

关键词(keywords):

<meta name="keywords" content="HTML, meta标签, SEO, 前端">

页面描述(Description)

<meta name="description" content="这是一个关于HTML元标签用法的详细介绍页面">

控制搜索引起的行为

<meta name="robots" content="noindex, nofollow">
#noindex:禁止搜索引擎索引本页。
#nofollow:禁止跟踪本页的链接。

4. 社交媒体卡片(open graph)

<meta property="og:title" content="页面标题">
<meta property="og:description" content="页面描述">
<meta property="og:image" content="https://example.com/image.jpg">
<meta property="og:url" content="https://example.com">

<script> 标签中 deferasync 的区别是什么?

<script> 标签中的 deferasync 都是用来控制脚本加载和执行行为的属性

没有src属性的脚本 defer和async 会被忽略

  1. 默认行为:
<script src="script.js"></script>
  • 加载:立即下载脚本,会阻塞html解析
  • 执行:脚本下载完后会立即执行,执行也会阻塞 html解析
  • 影响:可能会导致页面渲染延迟
  1. async(异步):
<script async src="script.js"></script>
  • 加载:异步下载脚本,不阻塞HTML解析

  • 执行:脚本下载完成后立即执行(无论HTML是否解析完成)

  • 特点:

    • 多个 async 脚本的执行顺序不确定(先下载完的先执行)。
    • 适合独立脚本,不依赖dom或其他脚本,若脚本操作DOM,可能会因为DOM未就绪报错
  • 影响

  1. defer(延迟)
  • 加载:异步下载脚本,不阻塞HTML解析
  • 执行: 脚本延迟到 html解析完成后,DOMContentLoaded 事件前按顺序执行

<img>srcsetsizes 属性如何实现响应式图片?

  • Srcset: 图片候选集,提供多个图片源,并指定每个源的宽度描述符(w)或像素密度描述符(x)
  • sizes:自定义渲染条件,告诉浏览器图片在不同视口下的渲染宽度(CSS像素)
<img src="default.jpg" 
     srcset="small.jpg 480w, medium.jpg 1024w, large.jpg 1600w"
     sizes="(max-width: 600px) 480px, 1024px">

为什么用 srcset 而不是 CSS 或 JavaScript?

  • 原生支持:浏览器可提前解析,避免布局抖动和额外请求。
  • 性能优化:减少高分辨率设备下载不必要的超大图片。
  • SEO 友好:图片内容能被搜索引擎正确抓取。

HTML 中如何实现懒加载(Lazy Loading)?原生支持的方式是什么?

html实现懒加载的方式有三种:

  • 原生方式:

优点:不用写javascript代码,理论上性能最优

缺点: 无法设置自定义触发距离或者加载回调

<img src='image.jpg' loading="lazy" alt='...'/>

优点:异步监听,比监听滚动事件更高效,可以自定义触发距离,不仅针对图片,任何广告、图片都可以作为懒加载的元素

缺点:首屏内容默认不会触发观察,就浏览器需要通过polyfill兼容

<html>
    <body>
        <img data-src="image.jpg" class="lazy" alt="...">
    </body>
</html>
<script>
const lazyImages = document.querySelectorAll('.lazy');
const observer = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      const img = entry.target;
      img.src = img.dataset.src; // 替换 data-src 为实际 src
      observer.unobserve(img);   // 停止观察已加载的图片
    }
  });
});

lazyImages.forEach(img => observer.observe(img));
</script>
  • 滚动视口方案:

优点 :兼容性最佳

缺点:性能较差,频繁触发滚动事件,肯能会造成布局抖动

window.addEventListener('scroll', throttle(() => {
  const lazyImages = document.querySelectorAll('.lazy');
  lazyImages.forEach(img => {
    if (isInViewport(img)) { // 判断元素是否进入视口
      img.src = img.dataset.src;
      img.classList.remove('lazy');
    }
  });
}, 200));

<canvas><svg> 的区别及适用场景。

canvas和svg的使用场景其实截然不同。

​特性
​类型​位图(像素级)​​矢量图(基于 XML)​
​渲染方式通过 JavaScript 动态绘制(即时渲染)声明式 XML 描述,由浏览器解析渲染
​DOM 支持无(绘制后无法单独操作图形元素)是(每个图形是 DOM 节点,可绑定事件)
​分辨率适应性依赖分辨率(放大变模糊)分辨率无关(无限缩放不失真)
​性能适合高频更新(如游戏、动画)复杂静态图形性能更好
​SEO/可访问性差(内容无法被搜索引擎或屏幕阅读器识别)好(文本和结构可被索引)

<iframe> 的优缺点是什么?哪些场景下会用到它?

iframe可以在一个页面中嵌入一个新的独立网页,比如一个网站中可以嵌入youtube、bilibili等外部视频,或者是嵌入一些广告。

优点:

  • 内容隔离,可以将第三方网站内容嵌入,不会影响原网站的内容,由于父页面和嵌入页面的js和 css隔离,也不会因嵌入页面被恶意攻击
  • 兼容性好,基本上所有现代浏览器都支持

缺点:

  • Seo: 搜索引擎会忽略掉ifream中的内容
  • 未设置 loading="lazy" 时会阻塞父页面 onload 事件。
  • 同源策略限制了不同域的的内容交互

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

  1. 基础输入类型
​类型​用途​示例
type="email"输入电子邮件地址(自动验证格式)
type="url"输入 URL(自动验证格式)
type="tel"输入电话号码(移动端弹出数字键盘)
type="search"搜索框(样式可能与普通文本不同)
type="color"颜色选择器
  1. 数字与范围输入
​类型​用途​属性
type="number"输入数字(支持步进增减)min, max, step(如 step="0.1")
type="range"滑块控件(选择数值范围)min, max, value(默认值)

如何通过 HTML 实现表单验证(无需 JavaScript)?

  1. 必填字段,使用required 属性强制用户填写字段
<input type="text" name="username" required>
<textarea name="feedback" required></textarea>

2. 使用 html5新增的输入类型自带格式验证:

<input type="email" name="email" required>
<input type="url" name="website">

3. 通过pattern 属性自定义规则

<input 
  type="password" 
  name="password" 
  pattern="^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d]{8,}$"
  title="密码需至少8位,包含大小写字母和数字"
>

<label> 标签的 for 属性和包裹输入框的区别?

两者在功能上其实是等效的,作用都是关联表单控件

  1. for属性(通过id关联)
<label for="username">用户名:</label>
<input type="text" id="username">

2. label标签包裹

<label>
  用户名:
  <input type="text">
</label>

整体看下来其实,for的功能和灵活性更高,开发复杂表单时,更推荐使用for + id的形式开发,但同时也要注意id冲突。

<datalist><select> 的区别是什么?

<datalist><select> 都用于提供输入选项,但它们在交互方式、灵活性和使用场景上有显著区别。以下是详细对比:

​特性
​交互方式​输入+下拉建议​(类似搜索框自动补全)​纯下拉选择​(只能选择预设选项)
​输入自由度允许用户输入自定义值仅限选择列表中的选项
​多选支持不支持可通过 实现
​数据结构通过 关联直接包裹 子元素
​浏览器支持IE10+ 和现代浏览器所有浏览器(包括旧版)
<label>输入城市:</label>
<input type="text" list="city-list">
<datalist id="city-list">
  <option value="北京">
  <option value="上海">
  <option value="广州">
  <option value="深圳">
</datalist>
<label>选择城市:</label>
<select>
  <option value="">--请选择--</option>
  <option value="bj">北京</option>
  <option value="sh">上海</option>
  <option value="gz">广州</option>
</select>

如何禁用表单的自动填充(autocomplete)?

设置 autocomplete="off" ,可以对整个表单(form)设置,也可以给输入框设置(input)

HTML 中哪些操作会导致重绘(Repaint)或回流(Reflow)?

在html和css中,某些操作会触发重绘或者回流,影响页面性能。

回流:浏览器重新计算元素的机和属性(尺寸、位置等),导致重新布局

重绘:浏览器重新绘制元素的可见样式(颜色、背景等),不影响布局

回流一定触发重绘,重绘不一定触发回流

触发回流的操作:

  1. 改变元素的尺寸、位置或布局
  2. 获取某些布局属性,如offsetWidth(强制触发回流)
  3. 文本或者图片的内容发生变化
  4. 删除/新增dom元素
  5. 窗口的缩放

触发重绘的操作:

  1. 修改不影响布局的视觉样式

优化建议 :

  1. 减少回流的次数

    1. 批量修改dom操作
    2. 将布局属性缓存起来,避免频繁操作读取
  2. 使用css优化

    1. 使用不会触发回流的元素代替(如: 使用 translateX 代替 left属性)
  3. 脱离文档流

    1. 对于有复杂动画的元素使用绝对定位,将动画元素脱离完当流,减少回流对其他元素的影响。

可以使用开发者工具检测

  • Chrome DevTools → Performance 面板记录回流/重绘事件。
  • 启用 Rendering → Layout Shift Regions 可视化回流区域。

预加载(Prefetch/Preload)如何通过 HTML 实现?

在 HTML 中,可以通过<link rel="preload"><link rel="prefetch">实现资源的预加载,优化页面性能。

  1. Preload(关键资源预加载)
  • as 指定资源类型,可选值包括scriptstylefontimage 等。
  • type指定 MIME 类型(如 font/woff2)。
  • crossorigin 跨域资源必须添加

特点

  • 浏览器会立即加载资源,优先级高于普通请求。
  • 适合渲染阻塞资源(如首屏 CSS)。
<link rel="preload" href="style.css" as="style">
<link rel="preload" href="app.js" as="script">
<link rel="preload" href="font.woff2" as="font" type="font/woff2" crossorigin>

2. prefetch(非关键资源预加载)

<link rel="prefetch" href="next-page.html" as="document">
<link rel="prefetch" href="image.png" as="image">

特点

  • 浏览器在空闲时加载资源,优先级较低。
  • 适合预加载 下一页内容或用户可能访问的资源。

什么是 HTML 的 contenteditable 属性?它有什么潜在问题?

contenteditable 是一个html属性,可以用于指定元素内容是否可以被用户所编辑。一般用于富文本编辑器。

<div contenteditable="true">可编辑的内容</div>

潜在问题:

  1. 可能会被粘贴恶意代码,造成xss攻击
  2. 内容的频繁编辑会触发回流和重绘,影响性能

localStoragesessionStorage 和 Cookie 的区别?

​特性​localStorage​sessionStorage​Cookie
​存储位置浏览器本地存储浏览器会话存储浏览器和服务器(通过 HTTP 头传输)
​生命周期永久存储,除非手动删除或清除浏览器数据仅限当前会话(关闭标签页/浏览器后清除)可设置过期时间(默认会话级)
​存储大小通常 5~10MB(不同浏览器可能不同)同 localStorage约 4KB(单个域名下总数有限制)
​数据共享范围同源的所有标签页和窗口共享仅限当前标签页(同源也不共享)同源共享(可通过 domain 和 path 控制)
​是否自动发送到服务器是(通过 HTTP 请求头自动发送)
​API 易用性简单的键值对接口(setItem/getItem)同 localStorage需手动解析字符串(或依赖库)
​安全性仅限客户端,无 HTTPS 自动保护同 localStorage可设置 Secure(仅 HTTPS)、HttpOnly(防 XSS)
​主要用途长期存储客户端数据(如用户偏好)临时会话数据(如表单草稿)身份验证(如 Session ID)、跟踪用户行为

HTML5 提供了哪些离线存储方案?

  • Web storage(详细内容参照上题)

    • Session storage
    • Local storage
  • Index DB

Index DB用来存储结构化数据,适合较大规模、复杂的数据,也可以存文件,同时支持事务、索引和一部的操作。存储容量也比较大,约为浏览器空间的 50%-80%

  • Service Worker

缓存网络请求(如 HTML、CSS、JS、图片等),实现离线访问。

详细的service worker 可以参考下面这篇文章:

juejin.cn/post/733980…

如何使用 Web Workers 在 HTML 中实现多线程?

Web Workers 是 HTML5 提供的 API,允许在后台线程中运行 JavaScript 代码,避免阻塞主线程。

基本用法:

  1. 先创建一个单独的worker脚本,用来执行复杂操作
// worker.js
self.onmessage = function(e) {
  const data = e.data; // 接收主线程发送的数据
  const result = heavyCalculation(data); // 执行耗时计算
  self.postMessage(result); // 将结果发送回主线程
};

function heavyCalculation(data) {
  // 模拟耗时计算(如大数据处理、复杂算法)
  let sum = 0;
  for (let i = 0; i < data; i++) {
    sum += i;
  }
  return sum;
}

2. 在主js文件中初始化worker

// main.js
const worker = new Worker('worker.js'); // 加载 worker.js

// 向 Worker 发送数据
worker.postMessage(100000000); // 发送一个较大的数字

// 接收 Worker 返回的结果
worker.onmessage = function(e) {
  console.log('计算结果:', e.data); // 输出 Worker 返回的结果
};

// 错误处理
worker.onerror = function(e) {
  console.error('Worker 错误:', e.message);
};
worker.terminate();

web worker适用场景:

  • CPU 密集型计算(如大数据分析、图像处理)。
  • 长时间运行的任务(如实时数据解析、WebSocket 数据处理)。
  • 避免 UI 卡顿(如复杂动画、图表渲染)。

target="_blank" 的安全风险是什么?如何避免?

会有反向标签劫持的风险,攻击原理如下:

  1. 用户点击带有 target="_blank" 的链接时

  2. 恶意网站链接window.opener API 获取对原页面的控制权

    1. 可以将原页面重定向到钓鱼网站
    2. 执行恶意操作

防范措施:

  1. 跳转标签添加 rel="noopener"****
<a href="https://example.com" target="_blank" rel="noopener">安全链接</a>

2. 跳转标签添加 rel="noreferrer"

<a href="https://example.com" target="_blank" rel="noopener noreferrer">安全链接</a>

也可以同时添加**noopener** noreferrer

<a href="https://example.com" target="_blank" rel="noopener noreferrer">安全链接</a>