知识点概览
HTML部分
1. DOM和BOM有什么区别?
- DOM(Document Object Model)
当网页被加载时,浏览器会创建页面的对象文档模型,HTML DOM 模型被结构化为对象树
用途: 主要用于网页内容的动态修改和交互,比如网页的局部更新、表单验证、创建动态列表等场景。
- 什么是Shadow DOM ?和普通DOM树有什么区别?
web component
做到真正的组件化- 原生规范,无需框架
- 天然与用户隔离,真正意义上的CSS scope
- 比如常用的
video
标签,我们通常只能在DOM结构中看到一个video
标签,但在设置中选择显示Shadow DOM
的时候,能看到它真正的结构
html
// 手动实现一个shadow DOM
<body>
<script>
customElements.define(
"my-shadow-dom",
class extends HTMLElement {
connectedCallback() {
const shadow = this.attachShadow({ mode: "open" });
shadow.innerHTML = "this is my shadow DOM!";
}
}
);
</script>
<my-shadow-dom></my-shadow-dom>
</body>
- BOM(Browser Object Model)
浏览器对象模型,document也是浏览器的对象
用途: 主要用于用于控制浏览器的行为,如页面导航、获取浏览器信息、管理浏览器窗口大小和位置等操作。
2. HTML中meta有什么作用?
作用:定义该html文档的元数据(字符集、页面描述、关键词、文档作者和视口设置等)
浏览器(如何显示内容或重新加载页面)、搜索引擎(关键词)和其他网络服务会用到元数据
html
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- 它为浏览器提供了关于如何控制页面尺寸和缩放比例的指令。 -->
<meta name="keywords" content="css, JavaScript, CSS3">
<meta name="author" content="guoshouying">
<meta name="description" content="this is my site.">
<meta http-equiv="refresh" content="10">
<!-- 每 10 秒刷新一次文档 -->
</head>
3. HTML5中语义化标签有哪些及特性
优点:1、利于搜索引擎优化SEO,2、方便开发和维护,3、无障碍访问(Accessibility)
4. 如何检查浏览器是否支持h5
- 检测特定的html5标签或者API,如 canvas,video,audio等标签,看浏览器能否正确识别
js
var canvas = document.createElement('canvas');
if (canvas.getContext) {
console.log("浏览器支持canvas");
} else {
console.log("浏览器不支持canvas");
}
5. 哪些标签可以优化SEO?
- 元标签(
meta
) - 语义化标签(
header
,section
,article
等)- 这些标签能够让搜索引擎更好地理解页面的结构和内容。 - 链接标签(
a
) - 图像标签(
img
)-alt
属性是搜索引擎理解图像内容与页面相关性的重要依据。
6. 对target='_blank'的理解?有什么安全性问题?如何防范?
作用:在新的窗口中打开链接指向的内容
- 安全问题
- 钓鱼攻击风险 :打开新的窗口后,通过
window.opener
可以访问原始窗口对象,进而获取到一些隐私信息,如登录状态,账号信息等,从而进行钓鱼攻击。 - 跨站脚本攻击(XSS)风险 :如果新打开的页面包含恶意脚本,并且能够通过
window.opener
与原始页面进行交互,就有可能将恶意脚本注入到原始页面中,导致用户信息泄露或者其他安全问题
- 钓鱼攻击风险 :打开新的窗口后,通过
- 防范措施
js
<a href="http://www.baidu.com" target="_blank" rel="norefferrer noopener">打开百度</a>
7. src和href的区别?
- src(Souce)
- 常用于img, script, iframe等标签,用于指定要加载到当前元素中的外部资源的位置。加载时,浏览器会停止对HTML文档的解析,直到获取并加载完指定的资源,然后再继续HTML解析。
- href(hypertext reference)
- 常用于a(超链接),link标签(链接样式表),用于指定目标资源的位置,这个资源和当前文档是引用关系,浏览器不会暂停HTML解析去执行它。a标签中只有点击的时候才执行加载该页面。对于
<link rel="stylesheet" href="styles.css">
,浏览器会在后台异步加载样式表,不会阻塞 HTML 文档的解析。 - href="javascript:void(0) " 和 href="#" 有什么区别?
href="javascript:void(0) "
:表示死链接,通常用于需要在点击链接时执行 JavaScript 代码,但不希望页面有任何跳转或刷新的情况:<a href="javascript:void(0)" onclick="doSomething()">点击我</a>
,如果页面javascript被禁用,将不工作。href="#"
:锚点,默认是#top
,页面会向上滚动,如果页面javascript被禁用,仍然工作。
- 常用于a(超链接),link标签(链接样式表),用于指定目标资源的位置,这个资源和当前文档是引用关系,浏览器不会暂停HTML解析去执行它。a标签中只有点击的时候才执行加载该页面。对于
8. script标签中的defer和async的区别?
- 相同点
- 都是实现脚本的异步加载,不会阻塞浏览器对HTML文档的解析,在后台下载脚本,提高网页性能及用户体验。
- 不同点
- defer:脚本加载完后不会 立即执行,等HTML解析完按顺序执行脚本。适用于脚本间有依赖顺序,或者需要操作DOM的场景。
- async:脚本加载完立即执行,且不按照顺序,哪个下载完的快先执行哪个。适用于不操作DOM的独立脚本,比如广告脚本,第三方统计脚本。
9. 什么是canvas & 什么时候用?
- 概念
- h5提供的标签,允许用JavaScript在画布上绘图(形状、线条、曲线、方框、文本和图像,以及颜色、旋转、透明度和其他像素操作)
- canvas是基于像素的,有一个二维的网格系统,原点为(0,0)在左上角,x轴水平向右,y轴垂直向下。
- 与SVG相比,SVG是可缩放矢量图形,使用XML来描述图形,可以方便的缩放,修改。canvas绘制的图形基于像素修改比较困难。
- 使用场景
- 游戏开发:简单的休闲游戏,如连连看,绘制图形。
- 可视化开发:柱状图,折线图等各种图表。
- 图像处理和特效:例如,实现图像的灰度化、模糊处理、旋转、缩放等效果。
- 动画制作:加载动画,粒子动画(比如模拟雪花飘落、烟花绽放等效果)等。
- 代码实现 Canvas API
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Canvss</title>
</head>
<body>
<!-- 创建canvas元素 -->
<canvas id="myCanvas" width="500" height="500"></canvas>
<script>
const canvasElem = document.getElementById('myCanvas');
// 创建绘图上下文context对象
const ctx = canvasElem.getContext('2d');
ctx.fillStyle = "#ff0000"; // 设置填充颜色
ctx.fillRect(0, 0, 200, 100); // 绘制矩形,fillRect(x, y, width, height)
ctx.clearRect(10, 10, 50, 50); // 清除矩形区域,clearRect(x, y, width, height)
ctx.strokeStyle = "red"; // 设置边框颜色
ctx.strokeRect(0, 102, 100, 50); // 绘制矩形边框,strokeRect(x, y, width, height)
ctx.beginPath(); // 开始绘制路径
ctx.moveTo(0,220); // 将画笔移动到指定的坐标点,不进行绘制,主要用于确定线条的起始点
ctx.lineTo(150, 220); // 画一条线段到指定位置
ctx.stroke(); // 绘制线段
// 绘制圆形
// x和y是圆心的坐标,radius是半径,startAngle和endAngle是起始角度和结束角度(以弧度为单位),counterclockwise是一个布尔值,用于指定是否逆时针绘制。
ctx.beginPath();
ctx.arc(100, 300, 50, 0, Math.PI * 2, true); // arc(x, y, radius, startAngle, endAngle, counterclockwise)
ctx.stroke();
</script>
</body>
</html>
svg和canvas画出的圆形区别
10. 渐进增强和优雅降级之间的区别?
- 渐进增强 (Progressive Enhancement)
- 一种网页设计和开发理念。它强调从最基本的、能在所有浏览器和设备上正常工作的核心内容和功能开始构建网页。然后,根据浏览器的能力和设备的特性,逐步添加更高级的样式、交互功能和性能优化。
- 例如,先构建一个只包含纯文本内容和基本链接的网页,确保它在最古老的浏览器或功能受限的设备(如一些低性能的移动设备)上能够正常访问和理解。之后,再为支持 CSS3 和 JavaScript 的现代浏览器添加样式(如渐变背景、动画效果)和交互功能(如表单验证、下拉菜单的动态效果)。
- 兼容性好,易于维护和扩展
- 优雅降级 (Graceful Degradation)
- 优雅降级的理念与渐进增强相反。它是从一个功能齐全、具有高级特性(如复杂的 CSS 样式、大量的 JavaScript 交互)的网站开始构建,然后考虑当浏览器或设备不支持某些高级特性时,如何让网站 "优雅地" 降级,即仍然能够提供基本的、可接受的用户体验。
- 用户体验优化在先,灵活性。
11. 什么是回流和重绘?
- 回流(重排)Reflow
- 浏览器重新计算页面中元素的几何属性(如位置,大小等)
- 修改元素的尺寸、位置、边距、填充等属性.
- 添加或删除可见的 DOM 元素.
- 改变元素的字体大小.
- 页面的尺寸变化(如窗口大小调整).
- 获取元素的几何属性(如
offsetWidth
、offsetHeight
等).
- 比如排队前面的一个人走了,后面所有人都要向前走一步,或者有人插队,后面所有人都要向后退,这就是回流
- 浏览器重新计算页面中元素的几何属性(如位置,大小等)
- 重绘 Repaint
- 浏览器重新绘制元素的过程
- image的宽高定了,只是换了src
- 改变元素的颜色,边框等属性
- 修改元素可见性(display:none改为block)
- 比如排队有人替你占位置,你来了,替你的那个人走了,不影响到后面的人,这就是重绘
- 浏览器重新绘制元素的过程
- 优化策略
- 使用虚拟DOM:现代化前端框架像 React、Vue.js 等都使用了虚拟 DOM 来优化 DOM 更新。当数据发生变化时,框架会先在虚拟 DOM 上进行操作,计算出新旧虚拟 DOM 的差异(这个过程称为 "diffing"),然后只将真正需要更新的部分应用到真实 DOM 上。这样可以避免不必要的 DOM 操作,从而减少回流和重绘。因为在虚拟 DOM 层面,可以高效地比较和计算出最小的更新范围,而不是像直接操作真实 DOM 那样,每次小的修改都可能引发大面积的布局重新计算和重绘。
- 避免内联样式的频繁修改: 内联样式(通过
style
属性修改样式)会导致浏览器立即重新计算样式和布局。如果需要频繁地修改元素的样式,最好使用类名切换或者外部 CSS 样式表来控制样式变化。 - 使用
display:none
代替visibility:hidden
: 缺点:在合适的场景下才能用。 - 脱离文档流(使用
position:absolute
或position:fixed
):需要谨慎使用,可能会带来布局上的复杂性。
12. iframe有哪些应用?如何处理iframe通信?
- 应用
- 最常见的一种微前端手段
- 利用iframe开发低代码平台
- 嵌入第三方内容(如广告,地图,AI助手等)
- 跨域
- 通信: window.postMessage方法
iframeA.html
html
<body>
这是页面A
<button onclick="onClick()">点击我</button>
<iframe id="iframe" src="./iframeB.html"></iframe>
<script>
//向iframe发送消息
const iframe = document.getElementById("iframe");
function onClick() {
iframe.contentWindow.postMessage("hello b页面", "*");
}
//监听iframe里的页面发出的消息
window.addEventListener("message", (val) => {
console.log("message", val);
});
</script>
</body>
iframeB.html
html
<body>
这是页面B
<button onclick="onClick()">点击我</button>
<script>
//向父页面发送消息
function onClick() {
window.parent.postMessage("message", "*");
}
//接受父页面传来的消息
window.addEventListener("message", (val) => {
console.log("valll", val);
});
</script>
</body>