【前端面试】HTML篇
HTML5 新特性
- 语义化标签: 引入新的语义化标签,如
header、footer、nav、article、aside等,使页面结构更具可读性和可维护性。 - 音视频处理: 引入
<audio>和<video>标签,使网页中嵌入音视频更加简单。 - Canvas/WebGL: 引入
<canvas>元素,允许通过 JS 在页面进行图形绘制。 - 拖拽功能: 引入拖放 API(Drag and Drop),使网页能更加方便支持拖放操作。
- 新的 API: 引入新的 JS API,如 History API、Geolocation API、File API 等,提供了更多的功能和能力。
- 本地存储: 引入本地存储功能,如
localStorage和sessionStorage,使网页可以在客户端存储数据。 - 表单控件: 引入一些新的表单控件,如日期选择器、范围输入等。
- requestAnimationFrame: 为了解决
setTimeout与setInterval时间间隔不稳定的问题,由系统而非 JS 控制刷新,用法与setTimeout类似,但时间间隔由系统决定。 - WebSocket: 新增的一种通信协议,用于 Web 实时推送,可以在浏览器和 Server 之间建立双向连接。
HTML5 语义化的优点
- 利于 SEO:搜索引擎能更好地理解页面结构,提升内容抓取效率和排名。
- 提升可访问性:屏幕阅读器等辅助技术能准确解读内容,帮助残障用户。
- 代码可维护性:结构清晰,便于团队开发和维护。
- 便于样式设计:为 CSS 提供了清晰的钩子。
在实际项目中,如何权衡语义化和无意义的 <div>
在实际项目中,应优先在 SEO、无障碍访问和核心内容区域 使用语义化标签,而在 纯视觉布局或功能组件 中灵活使用 <div>。
同时,通过工具和团队规范渐进式优化,避免过度设计。关键是要明确标签的职责——语义化标签传达内容结构,而 <div> 解决样式和功能问题。
script 标签中 defer 和 async 的区别
- async: 下载完成立即执行,顺序不保证,适用于无依赖的独立脚本。
- defer: 文档解析完成后按引入顺序执行,适用于依赖 DOM 或多个脚本需要按顺序执行的场景。
DOMContentLoaded 会受 defer 和 async 哪个影响?
defer脚本会在DOMContentLoaded事件触发前执行完毕。async脚本的执行与DOMContentLoaded没有固定顺序,DOMContentLoaded不会等待它。
DOCTYPE 的作用
声明 HTML 文档类型,触发浏览器标准模式,防止因进入怪异模式导致 CSS 布局错乱。
标准模式和怪异模式的区别?
- 标准模式:严格遵守 W3C 规范渲染页面。
- 怪异模式:沿用旧版浏览器(如 IE5)的非标准规则,导致盒模型、
margin、line-height、定位、float等行为不一致,同样的 CSS 在不同模式下呈现结果不同。
行内元素、块级元素、空元素
- 块级元素:独占一行,可设置宽高,可包含行内元素或块级元素。如
<div>、<p>、<h1>-<h6>、<ul>、<ol>、<li>、<section>、<article>、<header>、<footer>、<table>。 - 行内元素:不独占一行,宽高由内容决定,只能包含文本或行内元素。如
<span>、<a>、<img>、<strong>、<em>、<label>、<input>、<button>、<b>、<i>。 - 空元素:没有内容和结束标签。如
<br>、<hr>、<input>、<img>。
<a> 可以包块级元素吗?为什么 HTML5 支持?
HTML5 允许 <a> 标签包裹块级元素。
原因:为了方便将整个区域(如卡片、列表项)作为可点击的链接,从而改善交互体验。虽然包裹了块级元素,但其语义仍然是链接。
href 和 src 的区别
- href:引用资源。浏览器在解析到
href时,会并行下载资源(如 CSS、字体文件),但不会停止当前文档的处理。常用于<link>和<a>标签。 - src:嵌入资源。浏览器在解析到
src时,会暂停页面解析,下载、执行或渲染该资源(如 JS 脚本、图片、iframe),因为它会直接影响并成为文档的一部分。
为什么 CSS 用 href,JS 用 src
- CSS:作为样式规则,用于修饰文档,不直接改变文档结构。使用
href可以让浏览器在不阻塞页面渲染的情况下加载样式。 - JS:作为脚本,可能会修改 DOM 或执行其他操作,直接影响页面内容和行为。使用
src确保脚本在正确的时间点被执行,避免因 DOM 未加载完成而出错。
img 中的 title 和 alt 区别
- alt:图片无法显示时的替代文字,利于 SEO 和无障碍访问。
- title:鼠标悬浮时显示的提示信息,用于提供额外说明。
script 标签放在 <head> 和放在 <body> 底部的区别
- 放在
<head>中:脚本会优先加载和执行,但会阻塞页面渲染。如果脚本需要操作 DOM,必须配合defer或DOMContentLoaded事件,否则可能因 DOM 未生成而报错。 - 放在
<body>底部:页面内容会先完成渲染,脚本最后加载执行。此时 DOM 已完全可用,脚本可以安全地操作任何元素,且不会阻塞初次渲染。 - 现代最佳实践:
- 通用做法:
<head>+defer。 - 简单且依赖 DOM 的脚本:放
<body>底部。
- 通用做法:
DOM 操作
- 添加节点:
appendChild()/insertBefore() - 移除节点:
removeChild() - 替换节点:
replaceChild() - 复制节点:
cloneNode(true|false) - 创建节点:
createElement()/createTextNode() - 查找节点:
getElementById()/querySelector()/querySelectorAll()/getElementsByClassName()
节点操作对性能有影响吗?为什么要用 DocumentFragment?
有影响。频繁的 DOM 操作会触发重排和重绘,消耗大量性能。
DocumentFragment 是一个内存中的虚拟 DOM 节点,它不是真实 DOM 的一部分。向其添加节点时,不会触发页面的重排或重绘。
优点:可以将多次 DOM 操作在内存中一次性完成,然后将最终结果(DocumentFragment)一次性追加到真实 DOM 中,从而将多次重排/重绘优化为一次。
const list = document.getElementById('list');
const fragment = document.createDocumentFragment(); // 创建文档片段for (let i = 0; i < 10000; i++) {const li = document.createElement('li');li.textContent = `Item ${i}`;fragment.appendChild(li); // 在内存中操作,不触发重排
}list.appendChild(fragment); // 一次性插入到 DOM,只触发一次重排
canvas 和 svg 区别
| 特性 | Canvas | SVG |
|---|---|---|
| 类型 | 位图(像素) | 矢量图(路径) |
| 缩放 | 放大失真 | 放大不失真 |
| 操作方式 | 通过 JS API 逐帧绘制 | 通过 DOM 节点描述图形 |
| 性能 | 适合频繁重绘(游戏、动画) | 适合静态或少量交互图形 |
| 事件支持 | 无元素级事件,需手动计算 | 支持对图形元素绑定事件 |
| 适用场景 | 动态图形、游戏、数据可视化 | Logo、图表、地图 |
WebSocket
- 实现原理:
WebSocket 是基于 TCP 的全双工通信协议。客户端与服务端只需一次 HTTP 握手,成功后即可建立持久连接,进行双向数据传输。它支持分片消息,适合实时通信和大规模数据流场景。 - 优点:
- 真·双向通信:服务器可主动向客户端推送消息。
- 低延迟:握手后无需再带上繁重的 HTTP 头,数据量小,效率高。
- 无跨域限制:协议本身支持跨域。
- 缺点:
- 长连接维护:对后端服务的稳定性和并发处理能力要求较高。
- 兼容性:部分老旧浏览器不支持。
- 实现复杂:相比轮询,状态管理和消息推送逻辑更复杂。
iframe 有哪些优缺点
- 优点:
- 隔离上下文:天然的 JS、CSS 沙箱,避免样式和脚本冲突。
- 安全沙箱:可用于加载不受信任的第三方内容。
- 并行加载:
iframe的加载不会阻塞主页面的onload事件。
- 缺点:
- SEO 差:搜索引擎难以抓取
iframe中的内容。 - 样式难控制:难以修改
iframe内部的样式。 - 性能损耗:每个
iframe都相当于一个独立的页面,会增加内存和 CPU 消耗。 - 跨域限制:存在诸多跨域通信和访问限制。
- SEO 差:搜索引擎难以抓取
iframe 如何实现跨域通信?
使用 window.postMessage API 可以安全地实现 iframe 与父页面之间的跨域消息传递。
