重温前端三件套(一):HTML
DOCUTYPE的作用
DOCTYPE是document type (文档类型) 的缩写。 是HTML5中一种标准通用标记语言的文档类型声明,告诉浏览器文档的类型,便于解析文档。 不同的渲染模式会影响浏览器对 CSS 代码甚⾄ JavaScript 脚本的解析。它必须声明在HTML⽂档的第⼀⾏.
浏览器渲染页面的两种模式
- CSS1 Compat:标准模式(Strick mode),浏览器使用W3C的标准解析渲染页面。浏览器以其支持的最高标准呈现页面。
- BackCompat:怪异模式(混杂模式)(Quick mode),默认模式,页面以一种比较宽松的向后兼容的方式显示。
小实验
1 | |
DOCTYPE 不存在或者形式不正确会导致HTML或XHTML文档以混杂模式呈现,就是把如何渲染html页面的权利交给了浏览器,有多少种浏览器就有多少种展示方式。因此要提高浏览器兼容性就必须重视。
html语义化
根据内容的结构选择合适的标签
优点
- 增加代码可读性,结构清晰,便于开发和维护
- 对机器友好,文字表现力丰富,有利于SEO。SEO(Search Engine Optimization)是搜索引擎优化,为了让用户在搜索和网站相关的关键词的时候,可以使网站在搜索引擎的排名尽量靠前,从而增加流量。
- 方便设备解析(如盲人阅读器等),可用于智能分析
- 在没有 CSS 样式下,页面也能呈现出很好地内容结构、代码结构
常见的语义化标签
- title :页面主体内容
- header : 页眉通常包括网站标志、主导航、全站链接以及搜索框。
- nav : 标记导航,仅对文档中重要的链接群使用。
- section : 定义文档中的节(section、区段)。比如章节、页眉、页脚或文档中的其他部分。
- main,帮助到搜索引擎以及搜索工程师找到网站的主要内容,本身并不承载特殊的功能和意义。
- article: 定义外部的内容,其中的内容独立于文档的其余部分。
- aside : 定义其所处内容之外的内容。如侧栏、文章的一组链接、广告、友情链接、相关产品列表等。
- footer:页脚,只有当父级是body时,才是整个页面的页脚。
- address: 作者、相关人士或组织的联系信息(电子邮件地址、指向联系信息页的链接)。
meta标签
meta标签用来描述一个HTML网页文档的属性,例如作者、日期和时间、网页描述、关键词、页面刷新等。
meta标签的作用有:搜索引擎优化(SEO),定义页面使用语言,自动刷新并指向新的页面,实现网页转换时的动态效果,控制页面缓冲,网页定级评价,控制网页显示的窗口等。
meta分类
1)页面描述信息(NAME):
常用的选项有Keywords(关键字) ,description(网站内容描述),author(作者),robots(机器人向导)等。
核心逻辑:这一类主要写给机器(搜索引擎爬虫、浏览器插件)看的,用来描述这个网页的“身份”。
1. Keywords (关键字)
代码:
HTML
1
<meta name="keywords" content="在线动作识别, 计算机视觉, 深度学习, GIS工具">详细解释: 它曾是 SEO 的王者。你在这里填什么词,用户搜这个词就可能搜到你。
- 现状:由于早年被滥用(堆砌无关关键词),Google 早已完全忽略这个标签。但在某些企业内部搜索或小型搜索引擎中可能仍有权重。
透彻理解:虽然主流 SEO 用处不大,但在整理文档索引时,它依然是一个很好的“标签(Tag)”系统。
2. Description (网站内容描述)
代码:
HTML
1
<meta name="description" content="这是一个关于计算机视觉前沿研究的博客,重点讨论在线动作识别与GIS数据可视化的结合应用。">详细解释: 这是 SEO 的核心。当你的网页出现在百度或 Google 的搜索结果中时:
第一行蓝色大字是
<title>。下面那两行黑色的简介,抓取的就是这个
description的内容。
实战:写得吸引人,用户的点击率(CTR)就会高。如果不写,搜索引擎会随机抓取正文里的第一段话,通常语无伦次。
3. Author (作者)
代码:
HTML
1
<meta name="author" content="Zhang San, zhangsan@university.edu">详细解释: 声明网页的归属权。
实战:在学术网站、博客系统中常用。如果你的文章被爬虫抓取,这行代码是证明“这是我写的”的元数据证据之一。
4. Robots (机器人向导)
代码:
HTML
1
<meta name="robots" content="index, follow">详细解释: 这是给爬虫下的“死命令”。
content的值通常有两个维度组合:index/noindex:收录 vs 不收录(能否在搜索结果里搜到)。follow/nofollow:顺藤摸瓜 vs 到此为止(爬虫是否要继续爬这个页面里的链接)。
实战例子:你的“后台管理页面”或“测试版页面”,应该写
content="noindex, nofollow",防止被百度收录泄密。
2)HTTP标题信息(HTTP-EQUIV):
可用于代替name项,常用的选项有Expires(期限),Pragma(cache模式),Refresh(刷新),Set-Cookie(cookie设定),Window-target(显示窗口的设定),content-Type(显示字符集的设定)等。
核心逻辑:这一类主要写给浏览器看的。http-equiv 的意思是“等同于 HTTP 头部”。服务器本来应该在发响应包时告诉浏览器的信息,你可以通过这个标签在 HTML 里直接“补发”指令。
1. Expires (期限)
代码:
HTML
1
<meta http-equiv="expires" content="Wed, 26 Feb 2026 08:21:57 GMT">详细解释: 设置网页的保质期。
在指定时间之前,浏览器再次访问这个页面,会直接从本地硬盘缓存里读,不发网络请求。
注意:必须使用 GMT(格林威治标准时间)格式。
透彻理解:如果你设置了过期时间是“过去的时间”(如 1900 年),就等于告诉浏览器“立刻过期,不要缓存”。
2. Pragma (cache 模式)
代码:
HTML
1
<meta http-equiv="Pragma" content="no-cache">详细解释: 这是 HTTP/1.0 时代的遗留产物(现在多用
Cache-Control),但为了兼容性依然常用。- 作用:强制浏览器不要缓存页面。
实战:在你的股票交易页面、GIS 实时监控大屏页面,加上这一行,确保用户每次刷新看到的都是最新的实时数据,而不是本地的旧图。
3. Refresh (刷新)
代码:
HTML
1
2
3<meta http-equiv="refresh" content="5">
<meta http-equiv="refresh" content="5;url=https://www.baidu.com">详细解释: 很多老网站的“注册成功,即将跳转…”页面就是用这个做的。
注意:这对用户体验不太好(突然跳转),现在更多用 JavaScript 来控制跳转,因为 JS 可以给用户一个“倒计时”的视觉提示,而 meta 标签做不到。
4. Set-Cookie (Cookie 设定)
代码:
HTML
1
<meta http-equiv="Set-Cookie" content="UserLocation=China; expires=Fri, 30 Dec 2026 12:00:00 GMT; path=/">详细解释: 这是在没有服务器后端代码(如 PHP/Java)的情况下,直接通过 HTML 在用户浏览器里种下一个 Cookie。
实战:现在极少使用。因为把 Cookie 逻辑写在 HTML 里很不安全,且难以维护。现在的开发标准都是通过服务器 HTTP Header 或 JavaScript (
document.cookie) 来操作。
5. Window-target (显示窗口的设定)
代码:
HTML
1
<meta http-equiv="window-target" content="_top">详细解释: 这是给“框架网页”(Frameset)时代的遗物。
- 作用:强制当前页面在指定的窗口打开。比如
_top表示跳出所有框架,占满整个浏览器窗口。
- 作用:强制当前页面在指定的窗口打开。比如
透彻理解:这是为了防止别人的网站用
<iframe>把你的网站嵌进去(点击劫持的一种雏形)。现在通常用X-Frame-Options头部来代替它。
6. Content-Type (显示字符集的设定)
代码:
HTML
1
2<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta charset="utf-8">详细解释: 这是最重要的一行代码。
它告诉浏览器:“我这个文件是 HTML,里面的文字编码是 UTF-8。”
如果不写,浏览器可能会猜错(比如猜成 GBK),导致你的中文页面全是乱码(口口口或者古文符号)。
3):Content 项
核心逻辑:这一类不需要单独解释,因为它是配合前两类存在的。
关系比喻:
name或http-equiv是表格里的**“项目名称”**。content是表格里的**“填写内容”**。
你不能单写 content,它必须依附于前两者才有意义。
HTML5特性
第一阵营:更高效的 DOM 与 语义化(让代码更像代码)
这部分特性的核心目的是:消灭 jQuery,规范代码结构。
1. 新的选择器 (querySelector, querySelectorAll)
以前的痛点:为了找一个
class="box"的div,我们得用getElementsByClassName,或者引入沉重的 jQuery 用$('.box')。HTML5 的进化:直接原生支持 CSS 选择器语法。
document.querySelector('.box #btn'):直接拿到匹配的第一个元素。本质:浏览器引擎(C++层)直接解析 CSS 选择器,性能通常优于老旧的 JS 递归查找。
2. 语义化标签 (header, nav, section 等)
- 解释:我们在上一个话题已经深入探讨过(结构清晰、SEO 友好)。这里不再赘述。
3. History API (history.pushState)
深度解读:这是现代 SPA(单页应用,如 Vue/React) 的基石。
以前:改变 URL 必须刷新页面。
现在:你可以用 JS 修改浏览器地址栏的 URL,但不触发页面刷新。这让前端路由(Router)成为可能,实现了“点击跳转,页面不白屏”的体验。
第二阵营:通信与性能(让网页像原生 APP 一样快)
这部分与你关注的 OS 线程 和 网络协议 紧密相关。
1. 全双工通信 WebSocket
以前的痛点:要做网页聊天室或股票大屏,只能用 AJAX 轮询(每秒问服务器:有新消息吗?)。这非常浪费带宽和 HTTP 握手开销。
HTML5 的进化:
协议升级:HTTP 握手一次后,直接升级为 TCP 长连接。
全双工:服务器可以主动给客户端推数据,客户端也可以随时发数据。
GIS 场景:你的车辆实时轨迹监控,必须用这个,否则延迟太高。
2. 多任务处理 WebWorker
OS 视角:你知道 JS 是单线程的(主线程)。如果你的 GIS 页面要计算一千万个点的坐标,界面直接就卡死(ANR)了。
HTML5 的进化:
真·多线程:允许 JS 创建后台线程。
限制:Worker 线程不能操作 DOM(为了线程安全,避免锁竞争),只能做纯计算。
实战:Mapbox 加载大量 GeoJSON 数据时,解析工作就是在 Worker 里做的,所以地图拖动依然流畅。
3. 跨窗口通信 PostMessage
解释:解决了
iframe跨域通信的难题。原理:基于事件的消息传递机制。
window.postMessage(data, origin)是一种安全的跨域握手。
4. 页面可见性 visibilitychange
痛点:用户打开了 10 个标签页,你的网页虽然在后台,但还在疯狂跑动画或轮询,耗电且占 CPU。
进化:通过
document.hidden判断页面是否可见。如果不可见,暂停 WebGL 渲染或 WebSocket 心跳。
第三阵营:图形与多媒体(告别 Flash 时代)
1. Video 和 Audio
以前:必须装 Adobe Flash 插件,不仅发热大,还全是安全漏洞。
现在:
<video src="movie.mp4"></video>。浏览器原生解码,支持硬件加速。
2. Canvas + SVG
这是你 GIS 领域的两大神器,必须分清:
Canvas (位图):
本质:一个画布,JS 在上面画像素点。
特点:高性能,适合成千上万个物体(如 Mapbox 底图、游戏)。但放大后会失真。
SVG (矢量图):
本质:基于 XML 的 DOM 元素。
特点:无限放大不失真,每个图形都能绑定事件(click)。适合做图表(如 D3.js, ECharts)。但节点多了会卡。
第四阵营:存储与离线(断网也能用)
1. 本地存储 (LocalStorage / SessionStorage)
以前:只能用 Cookie。缺点是容量小(4KB),而且每次 HTTP 请求都会自动带上 Cookie,浪费带宽。
HTML5:
LocalStorage:存硬盘,永久有效(除非手动删),容量大(5MB+)。
SessionStorage:存内存,关掉浏览器窗口就没了。
2. 离线应用 Manifest
注意:你提到的
manifest(Application Cache) 已经被废弃了!现在的方案:Service Worker + Web App Manifest。它允许网页拦截网络请求,即使没网,也能返回缓存的 HTML/CSS,实现 PWA(渐进式 Web 应用)。
第五阵营:交互与设备能力(打通硬件)
1. 地理位置 Geolocation
API:
navigator.geolocation.getCurrentPosition()。原理:浏览器会综合利用 GPS(最准)、Wi-Fi热点(三角定位)、基站 IP 来确定位置。因为涉及隐私,必须弹窗询问用户。
2. 拖拽 API (Drag and Drop)
- 解释:以前要实现把文件拖进网页上传,或者把列表项拖拽排序,很难写。现在提供了原生的
ondragstart,ondrop事件。
3. 增强表单控件
Input 类型:
email,date,number,tel。核心价值:不在于样式,而在于移动端体验。
写
<input type="tel">,手机键盘会自动弹出数字键盘。写
<input type="email">,键盘会自动带上@符号。
4. FormData 对象
- 解释:以前用 JS 提交文件(二进制流)非常麻烦。现在
new FormData()可以模拟表单提交,直接把文件对象传给后端,配合 AJAX 使用极佳。
第六阵营:移除的元素(断舍离)
1. 纯表现元素 (font, center, big)
原因:关注点分离(Separation of Concerns)。HTML 只管结构(是什么),CSS 管表现(长什么样)。
替代:用 CSS 的
font-size,text-align: center。
2. 负面影响元素 (frame, frameset)
区别:
iframe(内联框架) 还在,但frameset(框架集) 没了。原因:
frameset会把一个页面割裂成几个独立的 HTML,导致 URL 混乱(你发给朋友的链接可能只显示左边栏),SEO 也是灾难。
总结
HTML5 实际上做了一件事:把浏览器变成了一个微型操作系统。
它有文件系统(File API, LocalStorage)
它有线程管理(WebWorker)
它有网络栈(WebSocket, Ajax)
它有图形卡驱动(Canvas/WebGL)
src 和 href 的区别
1. 核心定义:一句话区分
src (引入):“拿过来,变成本身。” (Embed)
- 它指向的内容,会替换当前标签,成为文档不可分割的一部分。
href (引用):“指过去,建立联系。” (Reference)
- 它指向的内容,是外部资源,当前文档只是和它建立了一个连接关系。
2. 深度对比表(建议收藏)
| 维度 | src (Source) |
href (Hypertext Reference) |
|---|---|---|
| 全称 | Source (源) | Hypertext Reference (超文本引用) |
| 本质动作 | 下载并替换/执行 | 建立链接关系 |
| 作用对象 | JS 脚本, 图片, 视频, iframe | CSS 样式, 超链接 (<a>), 图标 (favicon) |
| 浏览器解析 | 阻塞 (Blocking) | 并行 (Non-blocking) |
| 对待方式 | “停下手里的活,先搞定它!” | “你先在后台下着,我继续干活。” |
| 形象比喻 | 器官移植 (没它我不完整) |
穿衣服/拿地图 (它只是辅助我) |
3. 详细机制拆解
A. src 的“霸道” (Embed & Block)
当浏览器遇到 src 时,潜台词是:“这个东西是我的肉体,没有它我没法显示。”
暂停解析:浏览器会阻塞暂停构建 DOM 树(除非加了
defer/async)。下载执行:下载资源,如果是 JS 则立即执行,如果是图片则解码。
替换内容:
<script src="app.js">:这里不再是一个空标签,而是被app.js的代码逻辑填充了。<img src="face.jpg">:这个位置被图片的像素填充了。
B. href 的“友好” (Link & Parallel)
当浏览器遇到 href 时,潜台词是:“那个东西是我的参考资料,帮我拿一下,我先继续读文章。”
识别关系:浏览器看到
<link href="style.css">,知道这是一个样式表。并行下载:浏览器分出一个线程去下载它。
不阻塞 DOM:主线程继续解析 HTML,构建 DOM 树。不会因为 CSS 没下完就让页面白屏停止解析。
- 注:虽然不阻塞 DOM 解析,但 CSS 会阻塞最终的页面渲染(Painting),因为浏览器不想画出“裸奔”的丑页面。
4. 现代前端视角的补充
虽然 src 本质是阻塞的,但我们通过现代工程化手段“驯服”了它:
对于 JS (
script src):我们使用
defer(或type="module")。这让
src依然保持“引入”的本质,但把“阻塞”的副作用去掉了(变成了异步下载,最后执行)。
对于 CSS (
link href):我们依然坚持用
href。我们要拒绝使用 CSS 内部的
@import,因为它会破坏href的并行下载优势(因为本身并行下载href的css,假设碰到某个css里又通过@import引入了一个url的css,等于改成了串形的css下载)。
行内元素 和 块级元素有哪些
一、元素种类
1、行内元素
- 和其他元素都在一行上;
- 高,行高及外边距和内边距部分可改变;
- 宽度只与内容有关;
- 行内元素只能容纳文本或者其他行内元素。
- 不可以设置宽高,其宽度随着内容增加,高度随字体大小而改变,内联元素可以设置外边界,但是外边界不对上下起作用,只能对左右起作用,也可以设置内边界,但是内边界在 ie6 中不对上下起作用,只能对左右起作用
<a > <strong> <b> <em> <del> <span > <img> <input> <select>
2、块级元素
- 总是在新行上开始,占据一整行;
- 高度,行高以及外边距和内边距都可控制;
- 宽带始终是与浏览器宽度一样,与内容无关;
- 它可以容纳内联元素和其他块元素。
<h1>~<h6> <p> <div> <ul> <ol> <li> <div> <dl>
3、空元素
<br> <hr> <img> <input> <link> <meta>
二、行内元素和块级元素的转换
//定义元素为块级元素 display:block //定义元素为行内元素 display : inline //定义元素为行 display:inline-block
三、块级元素和行内元素的区别
我们区分 块级元素 和 行内元素,首先行内元素是在一行中能有多个的,块级元素是自己占一行的。
接着可以从三个方面来查看
- 是否占据一行,还是能多个处于一行中,行内是可以的;
- 是否可以设置宽高,行内是不可以的。
- 行内元素只可以容纳文本和其他行内元素,块级元素啥都可以容纳
总结
行内元素和块级元素很好区分,顾名思义,行内就是能都在一行里的,一行可以有多个 < a > 标签 ,可以有多个 < input > 标签,而同类的还有 < span > / < img > / < strong > 等,这不就很容易记住了。而块级元素就是要自己占一行的,那不就有 < div > ,还有我们使用的列表 < ul > / < ol >,除此之外还有 < h1 >~< h6 > / < p > 等等。
| 特性 | 块级 (Block) | 行内 (Inline) | 行内块 (Inline-block) |
|---|---|---|---|
| 代表标签 | div, p, h1, ul, li |
span, a, b, em |
img, input, button (天然特性) |
| 排列方式 | 独占一行,从上到下 | 并排显示,自动换行 | 并排显示,不会自动换行 |
| 宽/高 | 可设置 (默认宽100%) | 不可设置 (随内容) | 可设置 |
| Margin (外边距) | 上下左右都有效 | 只有左右有效,上下无效 | 上下左右都有效 |
| Padding (内边距) | 上下左右都撑开布局 | 左右撑开,上下仅视觉有效 | 上下左右都有效 |
| 包含关系 | 能包容一切 | 只能包容文本/行内 (a标签除外) | 能包容文本/行内 |
link 与 @import 的区别
一、语法结构
//link <link href="路径" rel="stylesheet" type="text/css" /> //import @import url(路径地址);
二、区别
1、从属关系区别
@import是 CSS 提供的语法规则,只有导入样式表的作用;link是HTML提供的标签,不仅可以加载 CSS 文件,还可以定义 RSS、rel 连接属性等。
2、加载顺序区别
一个并行,@import串行
3、兼容性区别
@import是 CSS2.1 才有的语法,可在 IE5+ 才能识别;link标签作为 HTML 元素,不存在兼容性问题。
4、DOM可控性区别
可以通过 JS 操作 DOM ,插入link标签来改变样式; @import 是在 dom 树渲染完才会进行渲染的,所以是不被 JavaScript 动态的修改的
常见的图片格式
| 图片格式 | 优点 | 缺点 | 使用场景 |
|---|---|---|---|
| GIF | 文件小,支持动画、透明,无兼容性问题 | 只支持256种颜色 | 色彩简单的logo、icon、动图 |
| JPG | 色彩丰富,文件小 | 有损压缩,反复保存图片质量下降明显 | 色彩丰富的图片/渐变图像 |
| PNG | 无损压缩,支持透明,简单图片尺寸小 | 不支持动画,色彩丰富的图片尺寸大 | logo/icon/透明图 |
| WEBP | 文件小,支持有损和无损压缩,支持动画、透明 | 浏览器兼容性相对而言不好 | 支持webp格式的app和webview |
iframe
iframe 元素 可以在一个网站里面嵌入另一个网站内容
优点
- 实现一个窗口同时加载多个第三方域名下内容
- 增加代码复用性
缺点:
- 搜索引擎无法识别
- 影响首页首屏加载时间(阻塞window.onload)
- 兼容性差
限制iframe访问另一个页面
老版:设置X-Frame-Options 响应头 ——是否允许网页通过iframe 嵌套
- deny:完全禁止任何网页嵌套
- sameorigin:只允许同源域名访问
- allow-from url:允许url的域名可嵌套
新版:设置Content-Security-Policy
CSP,内容安全策略,限定网页允许加载的资源,防范XSS攻击
"Content-Security-Policy": "frame-ancestors 'self'"//限定iframe的嵌套
判断 window.top 页面顶级窗口和 自身窗口 window.self 是否相等,若不等则是嵌入了iframe
defer 和 async
defer和async是script标签的两个属性,用于在不阻塞页面文档解析的前提线下,控制脚本的下载和执行。
先了解一下页面的加载和渲染过程:
- 浏览器发送请求,获取HTML文档开始从上到下解析并构建DOM
- 构建DOM过程中,若遇到外联样式声明和脚本声明,会暂停文档解析,并开始下载样式脚本和文件
- 样式文件下载完成后,构建CSSDOM;脚本文件下载完成后,解析并执行,再继续解析文档构建DOM
- 文档解析完成后,将DOM和CSSDOM进行关联和映射,最后将视图渲染到浏览器窗口
注意,在上述过程中,脚本文件的下载和执行是和文档解析同步的,即它会阻塞文档的解析,若控制的不好,会影响用户体验,造成页面卡顿。
因此我们可以在script中声明defer和async这两个属性。
defer:用于开启新的线程下载脚本文件,并使脚本在文档解析完成后执行。 async:HTML5新增属性,用于异步下载脚本文件,下载完毕立即解释执行代码。
共同点
- 都是异步加载外部脚本文件
- 不会阻塞页面的解析
区别
async表示异步加载,表后续文档的加载和渲染与JS脚本加载和执行并行进行,脚本文件一旦加载完成,会立即执行,我们无法预测每个脚本的下载和执行时间顺序,谁先下载好谁执行。
defer表示延迟加载,加载后续文档和JS脚本加载(仅加载不执行)并行进行,JS脚本的执行需要等待文档所有元素解析完之后,load和DOMContentLoaded事件之前执行,有顺序而言。
普通
<script>:表现:HTML 解析 -> 暂停 -> 下载 JS -> 执行 JS -> 继续 HTML 解析。
痛点:红色的“执行”和蓝色的“下载”强行打断了绿色的“解析”。
async(异步):表现:HTML 解析 + 下载 JS (并行) -> 暂停 HTML 解析 -> 执行 JS -> 继续 HTML 解析。
特点:下载不耽误事,但一旦下完,立刻打断 HTML 解析去执行。
defer(延迟):表现:HTML 解析 + 下载 JS (并行) -> HTML 解析完成 -> 执行 JS。
特点:下载不耽误事,执行也绝不打断 HTML 解析,等到最后才执行。