HTML学了什么?

HTML 整理

HTML 只是一个标记性的语言,本身没有什么学习难度,HTML5 是新一代的 HTML 标准,实现了一些新的元素和属性, 改进了本地存储并且添加了很多语义元素,使得代码或者页面更加语义化。语义化的好处在于对代码的理解更加简单,同时也为视力障碍人士改善了网页的可阅读性。

关于更多的细节参考 https://www.runoob.com/html/html-tutorial.html

HTML DOM

关于 DOM 的理解可以参考 https://developers.google.com/web/fundamentals/performance/critical-rendering-path/render-tree-construction

DOM 是文档对象模型的缩写,按照对对象的理解,DOM 就是浏览器生成的这个页面的对象,每一个 HTML 元素就是一个节点,通过 HTML 的嵌套关系生成子节点和父节点关系的树,元素的属性也是元素对应节点的子节点。

DOM 的树并不是普通的二叉树或者特殊的树

DOM 节点关系

关系其实还是挺复杂的。不过 DOM 提供了各种方法实现了对于节点或者元素的选择、修改。

获取目标元素节点是对于 JavaScript 脚本比较重要的一环,获取到节点后即可对节点所产生的事件进行脚本控制。

当然在 Vue 或者 React 等框架中有对应的方法可以更加方便的获取节点添加事件。

CSS DOM

css 也是有一个 DOM 树的通过将两棵树合并生成一个渲染树供浏览器对页面进行渲染。

HTML5的更新

上一代 HTML4.01 已经过去很久了,HTML5 更新了非常多的东西,整体的发展方向一个是语义化、一个是支持更多的多媒体类型。

语义化方面比如 headerfooternavtime等。多媒体方面通过 videoaudio 对视频、音频进行设置。

以下的 HTML 4.01 元素在HTML5中已经被删除:

  • <acronym>
  • <applet>
  • <basefont>
  • <big>
  • <center>
  • <dir>
  • <font>
  • <frame>
  • <frameset>
  • <noframes>
  • <strike>
  • <tt>

Canvas(画布)

HTML5 中的 Canvas 用于图形的绘制。

1
<canvas id="myCanvas" width="200" height="100"></canvas>

使用 JavaScript 进行绘制

1
2
3
4
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.fillStyle="#FF0000";
ctx.fillRect(0,0,150,75);

通过获取 DOM 节点,然后通过 getContext("2d") 方法获取到 Canvas 的一个对象,通过坐标进行一个像素的绘画。

getContext() 函数返回一个渲染上下文对象,参考 https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLCanvasElement/getContext

相关的操作可以参考 https://www.runoob.com/tags/ref-canvas.html

更多的案例可以参考 https://www.runoob.com/w3cnote/html5-canvas-intro.html

SVG(可伸缩矢量图形)

下表列出了 canvas 与 SVG 之间的一些不同之处。

Canvas SVG
依赖分辨率
使用 JavaScript 绘制
不支持事件处理器
弱的文本渲染能力
能够以 .png 或 .jpg 格式保存结果图像
最适合图像密集型的游戏,其中的许多对象会被频繁重绘
不依赖分辨率
使用 XML 进行绘制
支持事件处理器
最适合带有大型渲染区域的应用程序(比如谷歌地图)
复杂度高会减慢渲染速度(任何过度使用 DOM 的应用都不快)
不适合游戏应用

SVG 最大的好处是相比于普通的图形来说在放大后没有锯齿,因为他的图形是由数学去定义的,而不是像素绘画的。

更多的实例或者教学可以参考 https://developer.mozilla.org/zh-CN/docs/Web/SVG

MathML

提供原生的数学公式的编写,参考 https://developer.mozilla.org/zh-CN/docs/Web/MathML

拖放

菜鸟的一个实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
<style type="text/css">
#div1 {width:350px;height:70px;padding:10px;border:1px solid #aaaaaa;}
</style>
<script>
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));
}
</script>
</head>
<body>

<p>拖动 RUNOOB.COM 图片到矩形框中:</p>

<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<br>
<img id="drag1" src="/images/logo.png" draggable="true" ondragstart="drag(event)" width="336" height="69">

</body>
</html>

通过这个实例我们可以知道,一个元素是否可拖、是否可放是需要对 HTML 元素进行控制的。

  • 在拖动目标上触发事件
    • ondragstart - 用户开始拖动元素时触发
    • ondrag - 元素正在拖动时触发
    • ondragend - 用户完成元素拖动后触发
  • 释放目标时触发的事件:
    • ondragenter - 当被鼠标拖动的对象进入其容器范围内时触发此事件
    • ondragover - 当某被拖动的对象在另一对象容器范围内拖动时触发此事件
    • ondragleave - 当被鼠标拖动的对象离开其容器范围内时触发此事件
    • ondrop - 在一个拖动过程中,释放鼠标键时触发此事件

最重要的 draggable="true" 链接和图像默认是可拖动的。所以可以不用设置这个,不过其他的元素就需要进行一个配置了。

MDN 的文档参考 https://developer.mozilla.org/zh-CN/docs/Web/API/HTML_Drag_and_Drop_API

Geolocation(地理定位)

参考 https://developer.mozilla.org/zh-CN/docs/Web/API/Navigator/geolocation、 https://developer.mozilla.org/zh-CN/docs/Web/API/Geolocation

通过Navigator.geolocation 返回一个 Geolocation 对象,通过 getCurrentPosition() 方法提供成功或者失败的回调函数,获取当前的位置信息。

成功的时候返回的是一个 Position 对象,参考 https://developer.mozilla.org/zh-CN/docs/Web/API/GeolocationPosition。

Video

1
2
3
4
5
6
7
8
<video width="320" height="240" controls>
<source src="forrest_gump.mp4" type="video/mp4">
<source src="forrest_gump.ogg" type="video/ogg">
<track src="subtitles_en.vtt" kind="subtitles" srclang="en"
label="English">
<track src="subtitles_no.vtt" kind="subtitles" srclang="no"
label="Norwegian">
</video>

<track> 标签为媒体元素(比如 <audio> and <video>)规定外部文本轨道。

通过 source 标签确定这个视频或者音频的资源位置。多个格式的 source 可以进行一个容错,防止浏览器不支持某一格式。

视频的控件是可以自定义的,如果没有自定义的话会使用 controls 浏览器默认的控件。

文档可以参考 https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/video 获取更多详细信息。

更多的属性比如 preload 可以作为一个优化点,针对不同的视频和网站类型进行优化,提高网页运行速度。

https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLMediaElement 是JavaScript多媒体对象的文档,视频和音频都是继承这个对象的。

视频对象 https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLVideoElement,可以通过获取DOM节点使用 JavaScript 对这个视频对象进行操作或者自定义视频的控件。

Audio

1
2
3
4
5
<audio controls>
<source src="horse.ogg" type="audio/ogg">
<source src="horse.mp3" type="audio/mpeg">
您的浏览器不支持 audio 元素。
</audio>

格式与视频大概相当,通过 audio 标签定义一个音频,通过 source 标签确定资源路径并提供格式容错。

音频也可以像视频一样通过 JavaScript 进行操作,也是默认使用 controls 使用浏览器的默认控件。

参考 https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLAudioElement

Input

Input 是一个表单控件,用于输入某一类型的数据,在 HTML5 中可以设置更多类型的数据

  • color
  • date
  • datetime
  • datetime-local(带时区的时间
  • email
  • month
  • number
  • range
  • search(搜索栏
  • tel(电话
  • time
  • url
  • week

通过这些内置的 Input 类型可以方便很多,如果你觉得不放心可以使用 pattern 属性来对输入进行一个验证,这也是我觉得应该去做的。

在这些里面比较有意思的是 range 类型的 Input。因为他默认是一个滑动条,这个滑动条需要设置最大和最小值,默认每一跳是1,通过 step 属性设置每次滑动的间隔。

表单元素

HTML5 有以下新的表单元素:

  • <datalist>
  • <keygen>
  • <output>

比较关键的是 <datalist> ,因为这个元素可以帮助前端实现一些搜索联想的功能,实用性比较高。通过 list 属性绑定。

1
2
3
4
5
6
7
8
9
<input list="browsers">

<datalist id="browsers">
<option value="Internet Explorer">
<option value="Firefox">
<option value="Chrome">
<option value="Opera">
<option value="Safari">
</datalist>

<keygen> 元素他说是提供密钥对来进行用户验证,但是没有实际用过。(w3school 和菜鸟里面的实例代码都是用的 GET 方法,那还加密干嘛?)

表单属性

HTML5 的 <form\><input>标签添加了几个新属性.

<form>新属性:

  • autocomplete(类似于浏览器帮你记录的填写记录,在下一次输入的时候提供自动完成功能,password 类型 Input 不能开启该属性。
  • novalidate(取消 type 携带的格式验证,可以取消 required 属性

<input>新属性:

  • autocomplete(单独设置与 form 相反的属性(不然单独设置他干嘛
  • autofocus
  • form(让这个 Input 属于某一 form (通过 ID
  • formaction(覆盖 form 中的 action,只能用于 submitimage
  • formenctype(覆盖 form 元素的 enctype 属性,只能用于 submitimage,描述了表单提交到服务器的数据编码
  • formmethod(覆盖了 form 元素的 method 属性,只能用于 submitimage
  • formnovalidate(覆盖 <form> 元素的 novalidate 属性,只能用于 submit
  • formtarget(覆盖 <form> 元素的target属性,只能用于 submitimage
  • height 与 width(height 和 width 属性只适用于 image 类型的 <input> 标签。
  • list(绑定 datalist
    • min 与 max(限制包含日期和数字的 Input
  • multiple(适用于 email、file 类型,email 通过逗号分隔
  • pattern (regexp)(利用正则表达式对输入内容进行验证
  • placeholder
  • required
  • step(合法的数字间隔,min-max=1-10, step=3, 合法的就是1、4、7、10

更加清晰的语义化标签

HTML5 提供了新的语义元素来明确一个Web页面的不同部分:

  • <header> (注意是文档头部区域而不是网页头部区域,
  • <nav> (导航栏
  • <section> (章节
  • <article> (独立内容
  • <aside> (页面主区域以外的内容如侧边栏等
  • <figcaption>figure 的标题
  • <figure> (独立的流内容应和主内容相关,但是对文档流不产生影响(图像、图表、照片、代码等等)
  • <footer>

HTML5 语义元素

Web 存储,localStorage 和 sessionStorage

大型网页的加载优化始终是网页的一个设计关键点,因为需要加载的东西实在太多,用户的身份验证信息也太多,Cookie 过小的容量不能更好的满足需求。而且Cookie 一直在各种请求中被使用,容易造成信息泄露。

客户端存储数据的两个对象为:

  • localStorage - 用于长久保存整个网站的数据,保存的数据没有过期时间,直到手动去除。
  • sessionStorage - 用于临时保存同一窗口(或标签页)的数据,在关闭窗口或标签页之后将会删除这些数据。

这两个存储对象一般来说是不会被包含在请求中的,而且 localStorage 如果不去清除的话会一直存在,并不能像 Cookie 一样过期。

img

同源依然是浏览器缓存的关键点,localStorage 只是在同一网站下即可访问到,SessionStorage 需要同一浏览器的同一窗口下才可,并且在浏览器关闭后会被删除。

Web SQL

https://www.runoob.com/html/html5-web-sql.html

http://www.ruanyifeng.com/blog/2018/07/indexeddb.html

https://developer.mozilla.org/zh-CN/docs/Web/API/IndexedDB_API

首先,浏览器不一定支持,其次,在浏览器存储大量结构化数据,一般来说 LocalStorage 是可以满足需求了。

如果一定需要使用,还是用 IndexedDB 吧,主要是浏览器支持比较好一些。

应用程序缓存

首先,这个应用程序实际上还是浏览器运行的页面,就像是把网页变成一个类似于 Chrome 插件的东西,可以更好的提供一个离线环境下的浏览。

应用程序缓存为应用带来三个优势:

  1. 离线浏览 - 用户可在应用离线时使用它们
  2. 速度 - 已缓存资源加载得更快
  3. 减少服务器负载 - 浏览器将只从服务器下载更新过或更改过的资源。

如需启用应用程序缓存,请在文档的 标签中包含 manifest 属性:

...

每个指定了 manifest 的页面在用户对其访问时都会被缓存。如果未指定 manifest 属性,则页面不会被缓存(除非在 manifest 文件中直接指定了该页面)。

manifest 文件的建议的文件扩展名是:”.appcache”。

请注意,manifest 文件需要配置正确的 MIME-type,即 “text/cache-manifest”。必须在 web 服务器上进行配置。(这里说的是请求时的 header 中的 accept

参考 https://developer.mozilla.org/zh-CN/docs/Web/Manifest https://www.runoob.com/html/html5-app-cache.html

两个参考实例的格式并不一样,推荐使用 MDN 的 JSON 格式,

还不清楚这两个实例有啥区别。回头试一下。

Web Workers

参考 http://www.ruanyifeng.com/blog/2018/07/web-worker.html

https://developer.mozilla.org/zh-CN/docs/Web/API/Web_Workers_API

JavaScript 的单线程是由于浏览器限制,但是单线程会导致性能上限比较低,Web Worker 类似于协程,帮助主线程分担压力。操作看资料吧,就是创建对象、运行任务、终止对象。

服务器发送事件(Server-Sent Events)

绝大部分网页都是浏览器请求、服务器反馈、网页更新。SSE 用于浏览器自动获取来自服务器的更新。也就是说获得服务器推送。

参考 https://developer.mozilla.org/zh-CN/docs/Server-sent_events/EventSource

WebSocket

参考 http://www.ruanyifeng.com/blog/2017/05/websocket.html

https://developer.mozilla.org/zh-CN/docs/Web/API/WebSocket

同样也是为了实现服务器向客户端推送消息。

img

使用 WebSockets 或者 SSE 相比于客户端轮询更加节约带宽资源,节省服务器资源。