前端html面试常见问题
- 1. !DOCTYPE (文档类型)的作用
- 2. meta标签
- 3. 对 HTML 语义化 的理解?语义元素有哪些?语义化的优点
- 4. HTML中 title 、alt 属性的区别
- 5. src、href 、url 之间的区别
- 6. script标签中的 async、defer 的区别
- 7. 行内元素、块级元素、空(void)
- 8. Html5新特性
- 9. 浏览器渲染页面的步骤
- 10. DOM的重绘(Repaint)和重排(回流)(Reflow)
- 文章参考
1. !DOCTYPE (文档类型)的作用
DOCTYPE的全称是Document Type,对应中文:文档类型
<!DOCTYPE>必须声明在html文档的第一行
它的目的是告诉浏览器(解析器)以什么样(如html或xhtml)的文档类型定义来解析文档
<!-- 以html作为文档类型来解析 -->
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + Vue</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>
浏览器渲染页面有两种模式:标准模式、混杂模式。可以通过document.compatMode获得
-
标准模式(CSS1Compat):也是默认模式,浏览器使用W3C的标准解析渲染页面,
标准模式中,浏览器以其支持的最高标准呈现页面
-
混杂模式(BackCompat):也是怪异模式,浏览器使用自己的怪异模式解析渲染页面,怪异模式中,浏览器以一种宽松的向后兼容的方式显示,模拟老式浏览器的行为以防止站点无法工作。
DOCTYPE不存在或形式不正确会导致html文档以混杂模式呈现
。
2. meta标签
定义和用法:
<meta> 标签定义关于 HTML 文档的元数据。元数据是关于数据的数据(信息)。
<meta> 标签始终位于 <head> 元素 内,通常用于指定字符集、页面描述、关键词、文档作者和视口设置:
元数据不会显示在页面上,但可以被机器解析。
浏览器(如何显示内容或重新加载页面)、搜索引擎(关键词)和其他网络服务会用到元数据。
提示:meta 元素有多种不同用法,而且一个 HTML 文档中可以多个 meta 元素。
提示:通过 <meta> 标签,有一种方法让网页设计师控制视口(即用户在网页中可见的区域)(请参见下面的"设置视口"实例)。
注意:每个 meta 元素只能用于一种用途。如果想要使用的特性不止一个,那就应该在 head 元素中添加多个 meta 元素。
<head>
<meta charset="UTF-8">
<meta name="description" content="免费的 Web 教程">
<meta name="keywords" content="HTML, CSS, JavaScript">
<meta name="author" content="Bill Gates">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
meta有如下属性:
meta 元素有三种典型的用法:
- 指定名/值元数据对
1:指定各种名/值元数据对
meta 元素可以使用名/值对定义元数据,为此需要用到其 name 和 content 属性。
为搜索引擎定义关键字:
<meta name="keywords" content="HTML, CSS, JavaScript">
定义有关网页的描述:
<meta name="description" content="Free Web tutorials for HTML and CSS">
定义页面的作者:
<meta name="author" content="John Doe">
设置视口,改善网站在各种设备上的外观:
<meta name="viewport" content="width=device-width, initial-scale=1.0">
- 声明字符编码
使用 charset 属性声明该页面采用 UTF-8 字符编码:
<meta charset="UTF-8">
- 模拟 HTTP 标头字段
使用 http-equiv 属性和 content 属性,每 30 秒刷新一次文档:
<meta http-equiv="refresh" content="30">
在 HTML5 中的变化
charset 属性在 HTML5 中是新增的。
在 HTML4 中,http-equiv 属性可以有任意多个不同的值。而在 HTML5 中,只能使用本页提到的值。
HTML4 中的 scheme 属性在 HTML5 中已不再使用。
此外,现在已不再使用 meta 元素来指定网页所用的语言。
设置视口
HTML5 引入了一种方法,使 Web 设计者可以通过 标签来控制视口。
您应该在所有网页中包含以下 视口元素:
它为浏览器提供了关于如何控制页面尺寸和缩放比例的指令。width=device-width 部分将页面的宽度设置为跟随设备的屏幕宽度(视设备而定)。
当浏览器首次加载页面时,initial-scale=1.0 部分设置初始缩放级别。
下面分别是不带视口 meta 标签的网页、以及带视口 meta 标签的网页的例子:
3. 对 HTML 语义化 的理解?语义元素有哪些?语义化的优点
语义 = 意义, 语义元素 = 有意义的元素
根据内容来选择合适的标签
语义元素:
1.article>内容区域</article>
2.<section>区块</section>
3.<main>主要区域</main>
4.<aside>侧边栏</aside>
5.<dialog>定义对话框</dialog>
6.<header>头部</header>
7.<nav>导航</nav>
8.<footer>页脚</footer>
语义化的优点:
- 代码结构清晰:没有css的情况下,也能呈现出很好的内容结构
- 增加可读,开发者能清晰的看出网页的结构,便于团队的开发和维护
- 有利于SEO:方便浏览器爬虫更好的识别内容
4. HTML中 title 、alt 属性的区别
alt属性 用在img标签,当图片不显示的时候会出现 alt属性里面的内容,当图片显示的时候不会显示
title属性 用在除了html、head、script、meta、base、basefont之外的所有标签,title属性是当鼠标放在标签上的时候,会出现一些提示信息
5. src、href 、url 之间的区别
- 含义
- src 引用资源替代当前元素,在img、script、iframe中使用
- href 是超文本引用,指向网络资源所在位置,建立和当前元素或者锚点或者当前文档之间的链接
- url 是统一资源定位符,一般来说,对于同一服务器上的文件,应该总是使用相对url用于资源定位
".": 表示目前所在的目录,相对路径 "D:/aaa/": 表示根目录,绝对路径
- 区别
- a、link标签使用 href, href用于在涉及的文档和外部资源之间建立一个关系 ,href 指向网络资源所在位置,建立和当前元素(锚点)或当前文档(链接)之间的联系
- img、script、iframe标签使用src, 在可替换的元素上使用src ,在请求 src 资源时会将其指向的资源下载并应用到文档中,比如 JavaScript 脚本,img 图片
- url 是统一资源定位符,一般来说,对于同一服务器上的文件,应该总是使用相对url用于资源定位
6. script标签中的 async、defer 的区别
我们知道当浏览器加载html的时候一旦遇到了script标签,就会停下来先把script标签里面的内容给执行掉,如果script标签引入的是外部文件,那就必须等待下载和执行完才会继续往下加载,如果外部文件刚好是在一个网络情况较差的服务器上,这样整个网页的加载都会受到很大的影响,这就是同步带来的阻塞弊端。
async 异步 defer 推迟, 他们两个都是异步加载js,不同的是async是js一加载完就会马上执行,不管html有没有解析完毕,所以它有可能阻塞html解析。而defer要等到html解析完毕之后才执行,所以不会阻塞html解析
async和defer属性只有在script标签有src属性的时候才有效
小问题:
let script = document.createElement('script');
script.src = 'xxxxx';
// 以上这种形式创建的js是async还是defer呢?创建的script标签会默认设置async为true
7. 行内元素、块级元素、空(void)
行内:a、b、span、input、img、select、 strong
块级:p、div、h1、ul、ol、li、dl、dt、dd
空(也叫单标签元素):<hr>、<br>、<img>、<input>、<link>、<meta>
8. Html5新特性
-
标签语义化
-
表单功能增强
新增表单类型: 邮箱标签: <input type="email"> 数字标签: <input type="number"> 滑动条标签: <input type="range"> 搜索框标签: <input type="search"> 日期框: <input type="date"> 星期框: <input type="week"> 月份框: <input type="month"> 颜色框: <input type="color"> 网址框: <input type="url"> <input type="submit"> <input type="reset"> 新增表单属性: placehoder 输入框默认提示文字 required 要求输入的内容是否可为空 pattern 描述一个正则表达式验证输入的值 min/max 设置元素最小/最大值 step 为输入域规定合法的数字间隔 height/wdith 用于image类型<input>标签图像高度/宽度 autofocus 规定在页面加载时,域自动获得焦点 multiple 规定<input>元素中可选择多个值 新增表单事件: oninput 每当input里的输入框内容发生变化都会触发此事件 oninvalid 当验证不通过时触发此事件
-
新增了音频和视频
-
新增 canvas 绘图
// canvas用法 <canvas id="draw" width="300" height="300">当浏览器不支持 canvas 标签的时候会显示这行文字</canvas> let draw = document.querySelector("#draw"); console.log(draw); // 判断是否支持canvas元素 if (draw.getContext) { let context = draw.getContext("2d"); // 通过getContext("2d") 获取 2d 的上下文对象 context.fillStyle = "#fc5531"; context.fillRect(10, 10, 300, 300); // 通过fillRect方法绘制的矩形用指定的fillStyle颜色填充,四个参数分别是矩形的x、y坐标、宽、高 }
-
新增 svg 绘图
svg 和 canvas 的区别:
-
canvas 可以随时使用js绘制 2D 图形
-
svg 是基于xml的,意味着可以操作DOM,渲染速度较慢
-
在 svg 中每个形状都被当作是一个对象,如果 svg 发生改变,页面会发生重绘
-
canvas 是1像素1像素的渲染,如果改变某一个位置,整个画布会重绘
// svg用法 <svg> // text元素添加文本,x、y定义文本的起点和终点 <text x="0" y="10">svg text</text> </svg> <svg> // cx、cy分别表示新坐标 r是半径 fill是图形的颜色 <circle cx="20" xy="50" r="100" fill="#00b96b" /> </svg> <svg> // x, y 是起始坐标,width 和 height 是图形的宽高 <rect x="0" y="0" width="100" height="100" fill="#00b96b" /> </svg> <svg height="300" width="300"> <path d="M 100 100 L 200 200 H 10 V 20" fill="#1cbbb4" /> </svg> / d 包含方向命令。这些命令以命令名和一组坐标开始: M 表示移动,它接受一组 x,y 坐标 L 表示直线将绘制到它接受一组 x,y H 是一条水平线,它只接受 x 坐标 V 是一条垂直线,它只接受 y 坐标 Z 表示关闭路径,并将其放回起始位置 /
- 地理定位
- 使用 getCurrentPosition() 方法来获取用户的位置
- 可以基于此实现计算位置距离
-
拖放API
设置元素为可拖放:为了使元素可拖动,把 draggable 属性设置为 true<p>把图片拖放到矩形中:</p> <div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div> <br /> <img id="drag1" src="https://img-home.csdnimg.cn/images/20240218021830.png" draggable="true" ondragstart="drag(event)" /> function allowDrop(ev) { ev.preventDefault(); } function drag(ev) { ev.dataTransfer.setData("Text", ev.target.id); } function drop(ev) { ev.preventDefault(); var data = ev.dataTransfer.getData("Text"); ev.target.appendChild(document.getElementById(data)); } /* dragstart 事件在用户开始拖动元素或被选择的文本时调用 dragover 事件在可拖动的元素或者被选择的文本被拖进一个有效的放置目标时(每几百毫秒)触发 dragenter 事件在可拖动的元素或者被选择的文本进入一个有效的放置目标时触发 dragleave 事件在拖动的元素或选中的文本离开一个有效的放置目标时被触发 dragend 事件在拖放操作结束时触发(通过释放鼠标按钮或单击 escape 键) drag 事件在用户拖动元素或选择的文本时,每隔几百毫秒就会被触发一次 drop 事件在元素或文本选择被放置到有效的放置目标上时触发。为确保 drop 事件始终按预期触发,应当在处理 dragover 事件的代码部分始终包含 preventDefault() 调用 */
-
Web Worker
Web Worker 是在主线程之外运行的用于解决JS单线程中,持续较长的计算,而影响用户的交互
主要用法: 提供主线程和新线程之间数据交换的接口:postMessage、onmessage
// 01.html主线程 var workder = new Worker("./01.js"); // 创建指向工具js的实例对象 workder.postMessage("我是主线程发送的信息"); // 通过postMessage发送主线程的信息 workder.onmessage = function (evt) { //接收worker.js传过来的数据函数 console.log("worker.js发送来的数据=====", evt.data); //输出worker.js发送来的数据 }; // 01.js onmessage = function (evt) { var data = evt.data; //通过evt.data获得发送来的数据 postMessage(`${data}哈哈哈哈`); //将获取到的数据发送会主线程 };
-
Web Storage
Web Storage API 提供了浏览器可以存储键/值对的机制,其方式比使用 cookie 更直观
Web Storage 包含如下两种机制:
-
sessionStorage 为每一个给定的源(origin)维持一个独立的存储区域,该存储区域在页面会话期间可用(即只要浏览器处于打开状态,包括页面重新加载和恢复)。
仅为会话存储数据,这意味着数据将一直存储到浏览器(或选项卡)关闭。
数据永远不会被传输到服务器。
存储限额大于 cookie(最大 5MB) -
localStorage 做同样的事情,但即使浏览器关闭并重新打开也仍然存在。
存储的数据没有过期日期,只能通过 JavaScript、清除浏览器缓存或本地存储的数据来清除。
存储限额是两者之间的最大值
这两种机制是通过 Window.sessionStorage 和 Window.localStorage 属性使用,调用其中任一对象会创建 Storage 对象,通过 Storage 对象,可以设置、获取和移除数据项。对于每个源 sessionStorage 和 localStorage 使用不同的 Storage 对象——独立运行和控制sessionStorage 、 localStorage 可使用的API相同如下:
保存数据:localStorage.setItem(key,value) 读取数据:localStorage.getItem(key) 删除单个数据:localStorage.removeItem(key) 删除所有数据:localStorage.clear() 得到某个索引的key:localStorage.key(index)
-
WebSocket
WebSocket 是一种在单个 TCP 连接上进行 全双工 通讯的协议(双向通信协议)什么是全双工: 是通信传输的一个术语,通信允许数据在两个方向上同时传输,在能力上相当于两个单工通信方式的结合。全双工指可以同时进行信号的双向传输(A→B且B→A,)即A→B的同时B→A,是瞬时同步的 与双工通信对应的是单工通信,单工通信就是在只允许A向B发送信息,而乙方不能向甲方传送 。在全双工和单工之间,还有一种通信方式叫“半双工”,是指一个时间段内只允许A向B发送信息,另一个时间段内只允许B向A发送信息,也就是说A和B通过时间段的组合完成双向通信。 列举现实中的例子可以帮助我们更容易理解这些通信方式。 我们日常使用的移动电话、固定电话以及各种远程工作的会议系统都是全双工通信的方式,半双工的通信工具比较典型的是对讲机,某些调度系统也还在使用半双工的方式。单工通信依然非常普遍,例如广播(FM)、电视等
WebSocket 实现客户端和服务端之间的双向通信,允许服务端主动向客户端推送数据,在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就可以创建持久性的连接,并进行双向数据传输。
WebSocket 和 HTTP 的区别:
他们都是基于TCP的传输协议, WebSocket 可以双向发送和接受数据,而 HTTP 是单向的(HTTP通信只能由客户端发起,不具备服务器主动推送的能力), WebSocket 的使用,需要先进行一次客户端和服务器的握手,两者建立连接后才可以正常双向通信,而HTTP是一个主动的请求对应一个被动的响应
WebSocket 的协议标识符?
如果服务器网址是 HTTP 那么 WebSocket 对应的是 ws
如果服务器网址是 HTTPS 加密的 那么 WebSocket 对应的是 wss
WebSocket 是为了能够实现在 web 应用上与服务器进行双向通信的需求 而产生出来的协议,
相比于轮询 HTTP 请求的方式,WebSocket 节省了服务器资源,有效的提高了效率
WebSocket 常用方法:
- Socket.send():通过 Socket 向服务器发送信息
- Socket.close():关闭 Socket 连接
WebSocket 常用属性:
- Socket.readyState:获取当前链接状态0:正在连接中,1:连接正常可以通信,2:连接关闭中,3:连接已关闭/连接失败
- Socket.url:获取当前连接地址
- Socket.binaryType:获取传输的数据类型
WebSocket 生命周期:
- Socket.onopen:连接建立时触发
- Socket.onmessage : 客户端接收服务端数据时触发
- Socket.onerror : 通信发生错误时触发
- Socket.onclose : 连接关闭时触发
9. 浏览器渲染页面的步骤
1,解析html,生成DOM树;解析CSS,生成CSSOM树
2,将DOM树和CSSOM树结合,生成渲染树(Render Tree)
3,Layout(回流):根据生成的渲染树,计算它们在设备视口(viewport)内的确切位置和大小,这个阶段是回流
4,Painting(重绘):根据渲染树以及回流得到的几个信息,得到节点的绝对像素
5,Display:将像素发送给GPU,展示在页面上
10. DOM的重绘(Repaint)和重排(回流)(Reflow)
-
重绘
重绘: 元素样式的改变(但宽高、大小、位置等不变)比如我只是把当前元素的背景颜色变了
Outline、visibility、color、background-color等 -
重排
重排:元素的大小或者位置发生变化(当页面布局和几何信息发生变化的时候),触发了重新布局,导致渲染树重新计算布局和渲染如添加或者删除可见的DOM元素
元素的位置发生变化
元素的尺寸发生变化
内容发生变化(比如文本变化或者图片被另一个不同尺寸的图片所替代)
页面一开始渲染的时候,这个无法避免,因为回流是根据视口大小来计算元素的位置和大小的,所以浏览器的窗口尺寸变化会引发回流
回流就是结构得重新算这就是回流
注意:重排一定会触发重绘,重绘不一定触发重排 -
避免DOM的回流的方案
1,放弃传统操作DOM的时代,基于vue/react开始数据影响视图模式
Mvvm、mvc、virtual dom、dom diff
2,DOM操作的分离读写(现代的浏览器都有渲染队列的机制)offsetTop、offsetLeft、offsetWidth、offsetHeight、clientTop、clientLeft、clientWidth、clientHeight、scrollTop、scrollLeft、scrollWidth、scrollHeight、getComputedStyle、currentStyle....这些都会刷新渲染队列 <div id="box"></div> box.style.width = "100px"; box.style.height = "100px"; box.style.background = "red"; // => 重绘制 box.style.margin = "20px auto"; // => 以上代码会引发几次回流(重排)? // => 1次 // => 因为现代版浏览器都有“渲染队列”机制:发现某一行要修改元素的样式,不立即渲染,而是看看下一行,如果下一行也会改变样式,则把修改样式的操作放到“渲染队列中”.....一直到不再是修改样式的操作后,整体渲染一次,引起一次回流
读写分离:
box.style.width = "100px"; // => 写 console.log(box.offsetWidth) // => 读 box.style.height = "100px"; // => 写 console.log(box.offsetHeight) // => 读 box.style.background = "red"; // => 写 box.style.margin = "20px auto"; // => 写 // => 以上读的时候(console.log(box.offsetWidth)),会引发一次回流,所以以上代码会引发3次回流。所以要读写分离 box.style.width = "100px"; // => 写 box.style.height = "100px"; // => 写 box.style.background = "red"; // => 写 box.style.margin = "20px auto"; // => 写 console.log(box.offsetWidth) // => 读 console.log(box.offsetHeight) // => 读 // => 把读和写分开来做
3,样式集中改变
.box { width: 100px; height: 100px; background-color: aqua; margin: 20px auto; } <div id="boxId"></div> // 方式一: div.className = 'box' // => 方式二: div.style.cssText = 'width: 20px; height: 20px'
4,缓存布局信息(它的原理是读写分离)
div.style.left = div.offsetLeft + 1 + 'px' div.style.top = div.offsetTop + 1 + 'px' // => 改为 var curLeft = div.offsetLeft var curTop = div.offsetTop div.style.left = curLeft + 1 + 'px' div.style.top = curTop + 1 + 'px'
5,元素批量修改
文档碎片:createDocumentFragment// => 假设我想给box动态加10个 span <div id="box"></div> for (let i = 0; i < 10; i++) { let span = document.createElement("span"); span.innerHTML = i; box.appendChild(span); } // => 以上方法引发10次回流 // => 方式1: 使用文档碎片 let frg = document.createDocumentFragment(); // 文档碎片:存储文档的容器 for (let i = 0; i < 10; i++) { let span = document.createElement("span"); span.innerHTML = i; frg.appendChild(span); } box.appendChild(frg); frg = null // => 引发一次回流 // => 方式2: 使用模版字符串拼接 let str = ``; for (let i = 0; i < 10; i++) { str += `<span>${i}</span>`; } box.innerHTML = str; // => 引发一次回流
6,动画效果应用到position属性为absolute或者fixed的元素上,因为它们脱离文档流,不会引发其他元素的回流
7,CSS3硬件加速(GPU加速)
比起考虑如何减少回流重绘,我们更期望的是,根本不要回流重绘:transform/opacity/filters…这些属性会触发硬件加速,不会引发回流和重绘可能会引发的坑:过多使用会占用大量内存,性能消耗严重,有时候会导致字体模糊等
8,牺牲平滑度换取速度
每次1像素移动一个动画,但是如果此动画使用了100%的CPU,动画就会看上去是跳动的,因为浏览器正在与更新回流做斗争,每次移动3像素可能看起来平滑度低了,但它不会导致CPU在较慢的机器中抖动9,避免table布局和使用css的javascript表达式
文章参考
https://blog.csdn.net/weixin_62305533/article/details/139267167