面试题—HTML篇
HTML面试题
从浏览器地址栏输入url到页面渲染发生了什么?
推荐文章:从输入URL开始建立前端知识体系
总体来说分为以下几个过程:
1. 输入网址并解析
输入URL后,浏览器会解析出协议、主机、端口、路径等信息,并构造一个HTTP请求。浏览器发送请求前,会先判断是否命中强缓存策略,如果命中,直接从缓存中获取资源,如果没有命中,浏览器会发送请求,判断是否命中协商缓存,如果命中,直接从缓存获取资源。否则,直接从服务器获取资源
DNS域名解析,在发起http请求之前,浏览器首先要去获得我们想访问网页的IP地址,浏览器会发送一个UDP的包给DNS域名解析服务器。
2. TCP/IP连接:三次握手
第一次握手,客户端给服务器发送一个SYN报文,并指明客户端的初始化序列号 ISN。此时客户端处于 SYN_SEND 状态
第二次握手,服务器收到 SYN 报文之后,会以自己的 SYN 报文作为应答,并且指定了自己的初始化序列号 ISN,同时会把客户端的 ISN + 1 作为 ACK 的值,表示自己已经收到了客户端的 SYN,此时服务器处于 SYN_REVD 的状态
第三次握手,客户端收到 SYN 报文之后,会回应一个 ACK 报文,也是一样的把服务器的 ISN + 1 作为 ACK 的值,表示已经收到了服务端的 SYN 报文,此时客户端处于 established 状态
最后服务器收到 ACK 报文之后,也处于 established 状态,此时,双方建立连接
3. 发送HTTP请求
4. 服务器处理请求并返回HTTP报文
5. 浏览器渲染页面
首先解析 HTML,构建 DOM 树;然后解析 CSS,生成 CSS 规则树;合并 DOM 树和 CSS 规则树,生成 render 树;布局 render 树(Layout),负责各元素尺寸、位置的计算;最后绘制 render 树(Paint),绘制页面像素信息
6. 断开连接:TCP四次挥手
刚开始双方都处于 established 状态,假如是客户端先发起关闭请求,则:
第一次挥手:客户端发送一个FIN报文,报文中会指定一个序列号。此时客户端处于FIN_WAIT1状态
第二次挥手:服务端收到FIN之后,会发送ACK报文,且把客户端的序列号值+1作为ACK报文的序列号值,表明已经收到客户端的报文了,此时服务端处于CLOSE_WAIT状态
第三次挥手:如果服务端也想断开连接了,和客户端的第一次挥手一样,发送FIN报文,且指定一个序列号。此时服务端处于LAST_ACK的状态
第四次挥手:客户端收到 FIN 之后,一样发送一个 ACK 报文作为应答,且把服务端的序列号值 +1 作为自己 ACK 报文的序列号值,此时客户端处于 TIME_WAIT 状态。
需要过一阵子以确保服务端收到自己的ACK报文之后才会进入CLOSED状态,服务端收到ACK报文之后,就处于关闭连接了,处于CLOSED状态。
这个问题可以延伸出来的问题太多了!!
如何理解重排和重绘
推荐文章:如何回答如何理解重排和重绘
关键渲染路径(CRP)
关键渲染路径(Critical Rendering Path)是浏览器将 HTML,CSS 和 JavaScript 转换为屏幕上的像素所经历的步骤序列。
大致步骤是这样:在解析 HTML 时会创建 DOM,HTML 可以请求 JavaScript,而 JavaScript 反过来,又可以更改 DOM。HTML 包含或请求样式,依次来构建 CSSOM。
浏览器引擎将两者结合起来以创建 Render Tree (渲染树),Layout(布局)确定页面上所有内容的大小和位置,确定布局后,将像素 Paint (绘制)到屏幕上。
重排和重绘
重排(Reflow):元素的 位置发生变动 时发生重排,也叫回流。此时在 Layout 阶段,计算每一个元素在设备视口内的确切位置和大小。当一个元素位置发生变化时,其父元素及其后边的元素位置都可能发生变化,代价极高。
重绘(Repaint): 元素的 样式发生变动 ,但是位置没有改变。此时在关键渲染路径中的 Paint 阶段,将渲染树中的每个节点转换成屏幕上的实际像素,这一步通常称为绘制或栅格化。
参考回答
重排和重绘是浏览器关键渲染路径上的两个节点, 浏览器的关键渲染路径就是 DOM 和 CSSOM 生成渲染树,然后根据渲染树通过一个布局(也叫 layout)步骤来确定页面上所有内容的大小和位置,确定布局后,将像素绘制 (也叫 Paint)到屏幕上。
其中重排就是当元素的位置发生变动的时候,浏览器重新执行布局这个步骤,来重新确定页面上内容的大小和位置,确定完之后就会进行重新绘制到屏幕上,所以重排一定会导致重绘。
如果元素位置没有发生变动,仅仅只是样式发生变动,这个时候浏览器重新渲染的时候会跳过布局步骤,直接进入绘制步骤,这就是重绘,所以重绘不一定会导致重排。
强缓存、协商缓存
强制缓存就是向浏览器缓存查找该请求结果,并根据该结果的缓存规则来决定是否使用该缓存结果的过程。
协商缓存就是强制缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程。
src和 href的区别
src和href都是用来引用外部的资源,它们的区别如下:
src:表示对资源的引用,当浏览器解析到该元素时,会将资源嵌入到当前文档中元素定义的位置,例如当浏览器发现
<script src="index.js""></script>
页面的加载和处理会暂停,直到浏览器获取、编译和执行文件。它类似于将 js 文件的内容转储到
script
标签内。img
标签的情况类似。它是一个空标签,包含在其中的内容由src
属性定义。浏览器暂停加载,直到它获取并加载图像。href:表示超文本引用,它指定一些Web资源的位置,建立引用文档和外部资源之间的链接关系。常用在a、link等标签上。
例如:
<link rel="stylesheet" href="index.css"> |
浏览器识别到这个资源是一个样式表,并且页面的处理解析不会暂停,(渲染可能会暂停,因为浏览器需要样式规则来绘制和渲染页面)。
对 HTML 语义化的理解
语义化是指根据内容的结构化(内容语义化),选择合适的标签(代码语义化)。通俗来讲就是用正确的标签做正确的事情。
语义化的优点如下:
- 对机器友好,带有语义的文字表现力丰富,更适合搜索引擎的爬虫爬取有效信息,有利于SEO。除此之外,语义类还支持读屏软件,根据文章可以自动生成目录;
- 对开发者友好,使用语义类标签增强了可读性,结构更加清晰,开发者能清晰的看出网页的结构,便于团队的开发与维护。
<!--没有语义化--> |
常见的语义化标签:
- 元素放置的位置
<header></header> 头部 |
- 嵌入媒体
<video src="xxx.mp4"></video> 视频资源 |
- section 和 article
<section>
定义文档中的元素,例如章节、标题或具有相同主题的文档的任何其他区域。
<article>
包含本身有意义的内容,例如文章、博客和评论。
<section> |
- aside
表示一个和其余页面内容几乎无关的部分,通常,此信息将位于侧边栏或不妨碍主要内容的位置。例如:文章旁边出现的广告
<article> |
DOCTYPE及作用
DOCTYPE是document type(文档类型)的简写,是HTML5中一种标准通用标记语言的文档类型声明
作用:它的目的是告诉浏览器(解析器)应该以什么样(html或xhtml)的文档类型定义来解析文档,不同的渲染模式会影响浏览器对 CSS 代码甚至 JavaScript 脚本的解析。它必须声明在HTML文档的第一行。
浏览器渲染页面的两种模式(可通过document.compatMode获取):
- CSS1Compat:标准模式(Strick mode),默认模式,浏览器使用W3C的标准解析渲染页面。在标准模式中,浏览器以其支持的最高标准呈现页面。
- BackCompat:怪异模式(混杂模式)(Quick mode),浏览器使用自己的怪异模式解析渲染页面。在怪异模式中,页面以一种比较宽松的向后兼容的方式显示。
如果没有DOCTYPE的声明,那么浏览器就会进入怪异模式,那么样式啥的就会失效或怪异。
script标签中defer和async的区别
在补充知识有
script 是会阻碍 HTML 解析的,只有下载好并执行完脚本才会继续解析 HTML
defer 和 async有一个共同点:下载此类脚本都不会阻止页面呈现(异步加载),区别在于:
- async 执行与文档顺序无关,先加载哪个就先执行哪个;defer会按照文档中的顺序执行
- async 脚本加载完成后立即执行,可以在DOM尚未完全下载完成就加载和执行;而defer脚本需要等到文档所有元素解析完成之后才执行
meta 标签常用属性与用法
meta用来描述网页文档的属性,比如网页的作者,网页描述,关键词等,常用属性:
charset
,用于指定HTML文档的字符编码
<meta charset="UTF-8"> |
keywords
,页面关键词
<meta name="keywords" content="关键词"> |
description
,页面描述
<meta name="description" content="页面描述"> |
author
,页面作者
<meta name="author" content="author_name"> |
refresh
,页面刷新如:每30秒刷新一次文档:
<meta http-equiv="refresh" content="30"> |
应用:结合url实现页面的定时刷新或跳转
例:5s后跳转到你指定的页面(注意跳转到其他页面浏览器后退按钮是不能用的)
<!-- 跳转到某个你指定的网站 --> |
比如有一个场景:登录成功!xx秒后跳转到首页…
viewport
,适配移动端,可以控制视口的大小和比例视口是网页中用户可见的区域。它会随着设备的不同而不同
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
width=device-width:设置页面的宽度跟随设备的屏幕宽度(根据设备而变化)。
initial-scale=1.0:设置浏览器首次加载页面时的初始缩放比例
robots
,搜索引擎索引方式
<meta name="robots" content="index,follow" /> |
其中,content
参数有以下几种:
index
:告诉搜索引擎抓取这个页面follow
:告诉搜索引擎可以从这个页面上找到连接,然后继续访问抓取下去noindex
:告诉搜索引擎不允许抓取这个页面nofollow
:告诉搜索引擎不允许从此页找到链接、拒绝其继续访问
可以抓取本页,而且可以顺着本页继续索引别的链接(默认行为):
<meta name="robots" content="index, follow"> |
不允许抓取本页,但是可以顺着本页继续索引别的链接
<meta name="robots" content="noindex, follow"> |
可以抓取本页,但是不可以顺着本页继续索引别的链接
<meta name="robots" content="index, nofollow"> |
不允许抓取本页,也不可以顺着本页继续索引别的链接
<meta name="robots" content="noindex, nofollow"> |
HTML5 有哪些更新
总结:
(1)新增语义化标签:nav、header、footer、aside、section、article
(2)音频、视频标签:audio、video
(3)数据存储:localStorage、sessionStorage
(4)canvas(画布)、Geolocation(地理定位)、websocket(通信协议)
(5)input标签新增属性:placeholder、autocomplete、autofocus、required
(6)history API:go、forward、back、pushstate
语义化标签
header、nav、footer、artical、section、aside
媒体标签
- audio:音频
<audio src="" controls autoplay loop="true"></audio>
<!-- 属性
● controls 控制面板
● autoplay 自动播放
● loop="true" 循环播放
-->- video:视频
<video src="" poster="" controls width="" height=""></video>
<!-- 属性
● poster:指定视频还没有完全下载完毕,或者用户还没有点击播放前显示的封面。默认显示当前视频文件的第一帧画面,当然通过poster也可以自己指定。
● controls:控制面板
● width
● height
-->表单
表单类型:
<input type=""> |
- url : 验证URL
- number : 只能输入数字,其他输入不了,而且自带上下增大减小箭头,max属性可以设置为最大值,min可以设置为最小值,value为默认值。
- search : 输入框后面会给提供一个小叉,可以删除输入的内容,更加人性化。
- range : 可以提供给一个范围,其中可以设置max和min以及value,其中value属性可以设置为默认值
- color : 提供了一个颜色拾取器
- time : 时分秒
- date : 日期选择年月日
- datetime : 时间和日期(目前只有Safari支持)
- datetime-local :日期时间控件
- week :周控件
- month:月控件
建议都自己尝试一遍
表单属性:
placeholder :提示信息
autofocus :自动获取焦点
autocomplete=“on” 或者 autocomplete=“off” 使用这个属性需要有两个前提:
- 表单必须提交过
- 必须有name属性
required:要求输入框不能为空,必须有值才能够提交。
pattern=" " 里面写入想要的正则模式,例如手机号pattern=“^(+86)?\d{10}$”
multiple:可以选择多个文件或者多个邮箱
form=“form表单的ID”
表单事件:
- oninput 每当input里的输入框内容发生变化都会触发此事件。
- oninvalid 当验证不通过时触发此事件
- 进度条、度量器
- progress标签:用来表示任务的进度(IE、Safari不支持),max用来表示任务的进度,value表示已完成多少
<progress max="100" value="90"></progress> |
meter属性:用来显示剩余容量或剩余库存(IE、Safari不支持)
- high/low:规定被视作高/低的范围
- max/min:规定最大/小值
- value:规定当前度量值
- DOM查询操作
- document.querySelector():选择第一个满足的
- document.querySelectorAll():所有满足的
它们选择的对象可以是标签,可以是类(需要加点),可以是ID(需要加#)
- Web存储
- HTML5 提供了两种在客户端存储数据的新方法:
- localStorage:永久存储,需要手动清除
- sessionStorage:会话存储,当前会话关闭就会被清除
- 其他
- 拖放:拖放是一种常见的特性,即抓取对象以后拖到另一个位置。设置元素可拖放:
<img draggable="true" /> |
- canvas:提供了一个通过 JavaScript 和 HTML的元素来绘制图形的方式。它可以用于动画、游戏画面、数据可视化、图片编辑以及实时视频处理等方面。
<body> |
- SVG:SVG 指可伸缩矢量图形,用于定义用于网络的基于矢量的图形,使用 XML 格式定义图形,图像在放大或改变尺寸的情况下其图形质量不会有损失,它是万维网联盟的标准
- 地理定位:Geolocation(地理定位)用于定位用户的位置
img的 srcset 属性的作用?
srcset属性用于设置不同屏幕密度下,img 会自动加载不同的图片。
<img src="image-128.png" srcset="image-256.png 2x" /> |
实现在屏幕密度为1x的情况下加载image-128.png, 屏幕密度为2x时加载image-256.png
按照上面的实现,不同的屏幕密度都要设置图片地址,目前的屏幕密度有1x,2x,3x,4x四种,如果每一个图片都设置4张图片,加载就会很慢。所以就有了新的srcset标准。代码如下:
<img src="image-128.png" |
其中srcset指定图片的地址和对应的图片质量。sizes用来设置图片的尺寸临界点。
对于 srcset 中的 w 单位,是宽度描述符,例如,渲染一个 450 像素宽的图像对应的描述符字符串:
450w
。如果可视区域小于这个值,就可以使用这张图片。浏览器会自动选择一个最小的可用图片。这里的size意味着:默认显示128px, 如果视区宽度小于360px, 则显示340px。
size语法:sizes="[media query] [length], [media query] [length] … "
b与strong的区别、i与em的区别
- strong与b都表现为粗体,而strong标签有语义,是起到加重语气,强调的效果而b标签应用场合于:摘要中的关键字、评论中的产品名称,或其他典型的应该加粗显示的文字(除此之外无其它特别强调)。而搜索引擎更侧重strong标签。
- i与em都表现为斜体,i仅仅内容展示为斜体,em表示强调的文本
常用的行内元素、块级元素、空元素有哪些?
行内元素有:
a b span img input select strong
块级元素有:
div ul ol li dl dt dd h1 h2 h3 h4 h5 h6 p
空元素,即没有内容的HTML元素。空元素是在开始标签中关闭的,也就是空元素没有闭合标签:
- 常见的有:
<br>
、<hr>
、<img>
、<input>
、<link>
、<meta>
; - 鲜见的有:
<area>
、<base>
、<col>
、<colgroup>
、<command>
、<embed>
、<keygen>
、<param>
、<source>
、<track>
、<wbr>
。
- 常见的有:
补充:
<b>
应用场合如:摘要中的关键字、评论中的产品名称,或其他典型的应该加粗显示的文字(除此之外无其它特别强调)。不要将
<b>
元素与<strong>
、<em>
或<mark>
元素混淆。<strong>
元素表示某些重要性的文本,<em>
强调文本,而<mark>
元素表示某些相关性的文本。<b>
元素不传达这样的特殊语义信息;仅在没有其他合适的元素时使用它。(MDN)select :size属性设置显示几个,multiple设置能否多选
<select name="pets" id="pet-select" size="4" multiple>
<option value="">--Please choose an option--</option>
<option value="dog">Dog</option>
<option value="cat">Cat</option>
<option value="hamster">Hamster</option>
<option value="parrot">Parrot</option>
</select>
行内元素和块级元素的区别
一、行内元素和块级元素的区别
- 行内元素不会占据整行,在一条直线上排列,都是同一行,水平方向排列;块级元素会占据一行,垂直方向排列。
- 块级元素可以包含行内元素和块级元素;行内元素不能包含块级元素。
- 行内元素与块级元素属性的不同,主要是盒模型属性上,行内元素设置width无效,height无效(可以设置line-height),margin上下无效,padding上下无效。
二、行内元素和块级元素的相互转换
- 行内元素转化为块元素: display:block;
- 块元素转化为行内元素: display:inline;
对 web worker 的理解
Web Worker 为 Web 内容在后台线程中运行脚本提供了一种简单的方法。它是真正的操作系统线程,可以在当前页面的后台生成,以便于执行复杂且资源密集型的任务。
想象一下,如果有很多数据要从服务器获取,或者需要在 UI 上完成一些复杂的渲染。如果直接在该网页上执行此操作,则该页面的加载可能会出现问题,并会影响 UI。
为了缓解这种情况,我们可以简单地创建一个线程——即 web worker——并让 web worker 处理复杂的事情。
另外,可以通过一种非常简单的方式与 Web Worker 进行通信,该方式可用于在 Worker 和 UI 之间来回传输数据。
Web Worker 常见应用:
- 显示股票价格、实时活跃用户等实时数据的仪表板页面
- 从服务器获取大文件
- 自动保存功能
创建 Web Worker:
const myWorker = new Worker('worker.js'); |
Worker
是一个 API 接口,可让我们在后台创建线程。我们需要传递一个参数,即一个<worker_file>.js
文件,用于指定 API 需要执行的文件。
注意:一旦发起调用,就会创建一个线程。这个线程只和它的创建者通信,也就是创建这个线程的文件。
如果希望一个worker被共享或使用(应用在多个不同的页面),可以用 SharedWorker
创建
const myWorker = new SharedWorker("worker.js"); |
HTML5的离线储存
尚未实际操作
离线存储指的是:在用户没有与因特网连接时,可以正常访问站点或应用,在用户与因特网连接时,更新用户机器上的缓存文件。
原理:HTML5的离线存储是基于一个新建的 .appcache
文件的缓存机制(不是存储技术),通过这个文件上的解析清单离线存储资源,这些资源就会像cookie一样被存储了下来。之后当网络在处于离线状态下时,浏览器会通过被离线存储的数据进行页面展示
**如何更新缓存:**更新 manifest 文件、通过 javascript 操作、清除浏览器缓存
浏览器如何对 HTML5 的离线储存资源进行管理和加载?
- 在线的情况下,浏览器发现 html 头部有 manifest 属性,它会请求 manifest 文件,如果是第一次访问页面 ,那么浏览器就会根据 manifest 文件的内容下载相应的资源并且进行离线存储。如果已经访问过页面并且资源已经进行离线存储了,那么浏览器就会使用离线的资源加载页面,然后浏览器会对比新的 manifest 文件与旧的 manifest 文件,如果文件没有发生改变,就不做任何操作,如果文件改变了,就会重新下载文件中的资源并进行离线存储。
- 离线的情况下,浏览器会直接使用离线存储的资源。
什么是 iframe 以及优缺点
- 什么是 iframe 内联框架?
本质上,iframe(内联框架)是在文档中加载另一个 HTML 页面的HTML元素。它本质上是在父页面中放置另一个网页。
- 如何使用?
- 原理?
当 Web 浏览器遇到 iframe 元素时,它会创建一个新的 HTML 文档环境来加载其中的内容。它从引用的 src 或 srcdoc 中获取代码,并将其呈现为自己的网站,然后将其完全放在父浏览页面中。
子 iframe 是在父框架内的完整浏览环境。它可以独立于父级加载自己的JavaScript 和 CSS ,也可以从父站点异步刷新和加载。
父站点可以定义 iframe 的各个方面,例如大小、位置等。
- 应用场景?
通常用于将外部广告、视频、标签、地图或其他交互元素嵌入到页面中。
- iframe的优缺点
优点:
- 使用方便
- 浏览器兼容性较好
- 允许嵌入第三方内容
- 绕过 CORS (跨域)限制,实现跨子域通信
缺点:
减慢页面加载速度
第三方网站不受控制
- 所以如果你认为某个网站不安全,不要将其内容放入 iFrame 元素中
可能会影响搜索引擎优化
会产生很多页面,不容易管理
<label>
的作用是什么?如何使用?label标签来定义表单控件的关系:当用户选择label标签时,浏览器会自动将焦点转到和label标签相关的表单控件上。
使用方法1:
<label for="username">click me</label>
<input type="checkbox" id="username">点击click me 的时候也可以勾选上
使用方法2:
<label for="username">click me
<input type="checkbox" id="username"/>
</label>
Canvas 和 SVG的区别
- SVG
SVG可缩放矢量图形(Scalable Vector Graphics)是基于可扩展标记语言XML描述的2D图形的语言,SVG基于XML就意味着SVG DOM中的每个元素都是可用的,可以为某个元素附加Javascript事件处理器。
在 SVG 中,每个被绘制的图形均被视为对象。如果 SVG 对象的属性发生变化,那么浏览器能够自动重现图形。
<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 600 600"> |
其特点如下:
- 不依赖分辨率(放大缩小不失真)
- 支持事件处理器
- 最适合带有大型渲染区域的应用程序(比如谷歌地图)
- 复杂度高会减慢渲染速度(任何过度使用 DOM 的应用都不快)
- 不适合游戏应用
- Canvas:
Canvas是画布,通过Javascript来绘制图形,是逐像素进行渲染的。其位置发生改变,就会重新进行绘制。(Canvas 是一个 JavaScript 绘图 API)
<canvas id="myCanvas" width="578" height="200"></canvas> |
其特点如下:
- 依赖分辨率
- 不支持事件处理器(Canvas 没有 DOM )
- 弱的文本渲染能力
- 能够以 .png 或 .jpg 格式保存结果图像
- 最适合图像密集型的游戏,其中的许多对象会被频繁重绘
推荐文章:Canvas vs SVG
head 标签有什么作用,其中什么标签必不可少?
<head>
标签用于定义文档的头部,它是所有头部元素的容器。<head>
中的元素可以引用脚本、指示浏览器在哪里找到样式表、提供元信息等。
文档的头部描述了文档的各种属性和信息,包括文档的标题、在 Web 中的位置以及和其他文档的关系等。绝大多数文档头部包含的数据都不会真正作为内容显示给读者。
下面这些标签可用在 head 部分:<base>, <link>, <meta>, <script>, <style>, <title>
。
HTML
<base>
元素 指定用于一个文档中包含的所有相对 URL 的根 URL。一份中只能有一个<base>
元素。
其中<title>
定义文档的标题,它是 head 部分中唯一必需的元素。
说一下 HTML5 drag API
- dragstart:事件主体是被拖放元素,在开始拖放元素时触发。
- drag:事件主体是被拖放元素,在正在拖放被拖放元素时触发。
- dragenter:事件主体是目标元素,在被拖放元素进入某元素时触发。
- dragover:事件主体是目标元素,在被拖放在某元素内移动时触发。
- dragleave:事件主体是目标元素,在被拖放元素移出目标元素时触发。
- drop:事件主体是目标元素,在被拖放元素释放到目标元素时触发。 (阻止默认行为)
- dragend:事件主体是被拖放元素,在整个拖放操作结束时触发。(释放鼠标)