• 作者:老汪软件技巧
  • 发表时间:2024-09-08 11:02
  • 浏览量:

HTML 的标准字符编码格式是 UTF-8,强烈不建议大家使用 UTF-16 甚至是 UTF-32。如果使用非 UTF-8 的字符编码格式,在表单提交、URL 编码等等情况时可能会出现意外的结果。

除了字符编码要使用 UTF-8,还有一些限制需要注意:

如果你的 HTML 是通过 meta 元素指定字符编码的(指定字符编码的方式除了 meta 元素还可以使用上面说的 BOM),整个文档只能有这一个指定字符编码的 meta 元素,不能再有一个 meta 元素指定字符编码(请注意不是用来指定字符编码的 meta 元素可以有很多个)。

指定字符编码有以下几种方式:

Content-Type: text/html;charset=utf-8

<iframe sandbox srcdoc="

前端创可贴

"
>
iframe>

<meta charset="utf-8" />

<meta http-equiv="text/html;charset=utf-8" />

那么问题来了,如果我用的全都是 ASCII 字符,我还需要指定字符编码吗?毕竟任何字符编码格式都能正确解析 ASCII 字符。

这种情况字符编码格式还是需要指定的,虽然你的代码都是 ASCII 字符,但是其他情况例如用户通过表单输入的非 ASCII 字符、由脚本生成的 URL 等等,都需要指定字符编码格式。所以不管怎么样,都要通过上面的任意一种方式指定字符编码格式。

DOCTYPE

DOCTYPE(Document Type Declaration,文档类型声明),用来告诉浏览器当前页面的 HTML 版本是多少,确保不同的浏览器对于同一个页面的解析结果是一样的。

对于 HTML 4.01,DOCTYPE 声明引用了一个 Document Type Definition(DTD,文档类型定义),DTD 定义了一个 XML 文档的结构和合法元素,HTML 4.01 是基于标准通用标记语言(Standard Generalised Markup Language,SGML) 的,所以在 DOCTYPE 声明中引用 DTD 是很有必要的。

HTML 4.01 把 DTD 分为strict、transitional 以及 frameset 3 种类型,各有各的用处,由于 DTD 限制较多,使用时较不方便,已逐渐被 W3C XML Schema 等所取代。

HTML 4.01 的 DOCTYPE 写法还是比较繁琐的:

HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">

对于 HTML5 规范来说,DOCTYPE 由以下部分组成:

不区分大小的 ;一个或多个 ASCII 空白字符;不区分大小写的 html;可选的历史遗留的 DOCTYPE 字符串(用于不能输出带有短 DOCTYPE 即 的 HTML 标记的 HTML 生成器),例如 ;0 或多个 ASCII 空白字符;> 符号。

简单来说,就是:

html>

出于历史原因,DOCTYPE 的声明是必需的,如果省略了 DOCTYPE,浏览器可能会使用一种与某些规范不兼容的渲染模式,所以为了让不同的浏览器都能遵循 HTML 规范,能有一样的渲染结果,我们一定要记得声明 DOCTYPE。

ASCII 空白字符

介绍一下上面说到的 ASCII 空白字符(ASCII whitespace),可以是 TAB、LF(Line Feed)、FF(Form Feed)、CR(Carriage Return)或者空格,其中 TAB 和空格我们都认识,这个 LF、FF 和 CR 又是什么东西呢?

早期计算机系统常使用电传打字机作为控制台设备,CR 是将打印头回车移动到第一列,LF 是将纸张向上移动,需要使用 CR+LF 字符序列结合起来将打印头定位在新行的开头,相当于是先打印头回到第一列,然后再纸张向上移动,结合起来就是换行的操作了。这个习俗被 Windows 操作系统继承了,所以可以看到 Windows 操作系统的换行符是 CRLF。

而 Unix、Linux 等系统使用单独的 LF 作为换行符,这就导致 Windows 和类 Unix 操作系统之间造成了冲突,在一个操作系统上编写的文件无法正确格式化或由另一个操作系统解释。所以像 VS Code 这种编辑器就提供了 2 种换行符:

而 FF 是指换页符号,将光标从当前页跳到下一页的顶部,通常这个符号也会产生 CR,即光标在下一页的第一列。

元素

HTML 有 6 大类元素:

void elements(空元素),不包含内容,不需要结束标签,也不需要开始标签自闭合的元素。

元素:area, base, br, col, embed, hr, img, input, link, meta, source, track, wbr。这些元素不能有内容,也不能有结束标签,也不需要自闭合。

_html的基本语法规则_html5语法规范

<br>
<hr>
<input type="text">

如果让这些元素自闭合,也不会有问题,在浏览器中会自动去掉自闭合:

<div>前端创可贴div>
<hr />

如果给他们加上结束标签,渲染不会有问题,但是如果加上了结束标签还加上了内容,浏览器的渲染就会有问题了:

<div>前端创可贴div>
<hr>xxxhr>
<input type="text">yyyinput>

可以看到元素的内容溢出到元素外面去了。

the template element(模板元素),用于在页面加载时不显示的内容,但可以通过 JavaScript 克隆和插入到文档中。

元素:template。每个模板元素都有模板内容(template contents),模板内容存储在一个 DocumentFragment 对象里。这个 DocumentFragment 对象又是个啥呢?看到这个 api 你应该就认识了:document.createDocumentFragment(),即可创建一个 DocumentFragment 对象,它其实是一个轻量版的 Document 对象,可以在它身上挂一些 DOM 子树,此时并不会影响渲染、引发回流重绘等,说白了就是不会渲染到页面上。可以一次性将 DOM 子树挂到当前的 DOM 树上,仅引发一次回流重绘,而不是分开挂载从而引发多次回流重绘。

template 元素里的内容默认是不会挂在 DOM 树上的:

<div>大家好,我是:div>
<template id="template">
  <div>前端创可贴div>
template>

从 DOM 结构中也可以看到,template 元素里的内容,会存储在一个 DocumentFragment 对象里。

通过 Javascript 可以获取 template 元素里的内容并且克隆,然后渲染到页面上:

<div>大家好,我是:div>
  
<template id="template">
  <div>前端创可贴div>
template>
<script>
  const clone = template.content.cloneNode(true);
  template.parentNode.appendChild(clone);
script>

插句题外话,观察上面代码,可以发现我是直接用 template 变量的,而没有获取 DOM 元素,原因是当 HTML 里某个元素有 id 属性时,可以不用通过 document.getElementById() 这样的方式获取元素,id 属性值已经映射了一个全局变量名,变量的值就是该 DOM 元素。

raw text elements(原始文本元素),其内容被视为原始文本的元素,浏览器不会对其内容进行解析。

元素:script, style。原始文本元素的内容可以是文本内容,但是不能误包含结束标签的模式,否则会被浏览器解析为元素的结束标签。

escapable raw text elements(可转义原始文本元素),其内容可以包含转义序列的原始文本。

元素:textarea, title。可转义原始文本元素的内容可以是文本内容和字符引用(&开头,;结尾,中间的字符匹配上预定义的命名字符引用,例如 代表空格),但是不能是无效的字符引用(不能匹配预定义的命名字符引用),以及和上面的原始文本元素一样,不能误包含结束标签的模式。

foreign elements(外来元素),来自非 HTML 命名空间的元素,主要是 SVG 和 MathML 元素,这些元素在 HTML 文档中使用,但属于不同的 XML 命名空间。

元素:MathML 命名空间和 SVG 命名空间的元素。开始标签不是自闭合时,内容可以是文本内容、字符引用、CDATA 区段(用于在 XML 和 HTML(主要在 XHTML 中)文档中标记不需要解析的文本内容,在 CDATA 区段中的所有内容都会被当作纯文本处理,不会被解析为标签或实体,通常用于嵌入 XML 片段)、其他元素和注释,但是文本不能包含 可选的文本内容,但是不能包含 ]]> 字符;]]> 字符。

<p>You can add a string to a number, but this stringifies the number:p>
<math>
 <ms>ms>
 <mo>+mo>
 <mn>3mn>
 <mo>=mo>
 <ms>ms>
math>

CDATA 区段大家混个眼熟就可以了,平时是用不到的。

注释

注释由这几部分组成:

或者 --!> 字符,也不能以 字符结尾。可以以 字符结尾,例如 。--> 字符。

注释在 DOM 树中也是一个有效的节点,并且通过父元素的 childNodes 属性可以获取到注释节点(这个属性还可以获取到 ASCII 空白字符节点),但是父元素的 children 属性会过滤掉注释节点和 ASCII 空白字符节点。

结束语

我们一起学习了 HTML 的语法规范,学习到了许多平时很容易被我们忽略的一些细节。

也做了很多相关知识的扩展,大家可以看到学习 HTML 并不是仅仅学习 HTML 这一门语言就足够了,毕竟它是要运行在计算机上,就会有一些计算机相关的基础知识需要我们学习,大家切记不要排斥这些基础知识的学习,在未来的某一天一定会用到的,一定要重视我们平时的知识积累和储备,或许在未来某一天看到一个知识点的时候,会突然茅塞顿开,对于学习新知识的速度和接受能力,也会大大上升的~

这一章的介绍就结束了,咱们下一章再见啦。