使用HTML5编写文档
为何使用HTML5来编写文档
使用HTML5来编写文档有以下好处:
- 方便共享
- 版面效果佳良
- 快速转换为其他格式的文档
- 充分利用HTML技术的各种优势
- 不受厂商与平台限制
- 编辑环境自由
因此,若有可能,应使用HTML5来编写文档。
本文从编写一个最简单的HTML5文档开始,探讨在各阶段其与一篇成熟的文档之间存在的差距,并通过运用各种技术来达到效果,或缩短距离,最后力使其成为一篇漂亮、出色的文档。
一个HTML5文档的格式
<!DOCTYPE html>
<html>
<head>
<title>Sample HTML5 Page</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<h1>Sample HTML5 Page</h1>
</body>
</html>
关于源代码标签
pre是必须用的。有些用户还使用pre code的方式。但code是行内元素。因此,若要显示一整段的代码,应只使用pre就行了。DocBook将programlisting也只是转换为pre而已。pre的目的在于保留空格和换行符。
使用article编写文档内容
在着重于网页结构的网页中,可不使用article标签。但如果该网页侧重于展示一篇文章,则应使用article。
下面是使用article的一个简单例子。
<body>
<article>
<header>
<h1>My First Article</h1>
<p class='authorinfo'>Sarkuya, <time>2019-04-25</time></p>
</header>
<section class='chapter'>
<h1>Chapter 1: Get Ready</h1>
<p>Go ahead to get ready for this game.</p>
</section>
<section class='chapter'>
<h1>Chapter 2: Run</h1>
<p>Don't forget to run away if dangerous.</p>
</section>
<section class='appendix'>
<h1>Appendix 1: DocBook</h1>
<p>Think of DocBook always.</p>
</section>
<section class='reference'>
<h1>参考书目</h1>
<ul>
<li><a href="" target="_blank">abc</a></li>
</ul>
</section>
<footer><p class="copyright">All rights reserved.</p></footer>
</article>
</body>
设定h1的值
article的header及section之下均有h1标签。这里的h1取意为相应章节之下的最大标题,而非h1之本义。因此,需对这些h1设定相应的大小。
font-size的绝对值及相对值
当使用字面符而非em, px等单位来表示大小时,font-size分为两种。
一种是绝对大小。有以下几种规格:
- xx-large
- x-large
- large
- mediumn
- small
- x-small
- xx-small
其与H1 - H6的关系详见下表。
| 绝对值 | HTML标题 | 例子 |
|---|---|---|
| xx-large | h1 | xx-large text |
| x-large | h2 | x-large text |
| large | h3 | large text |
| medium | h4 | medium text |
| small | h5 | small text |
| x-small | [N / A] | x-small text |
| xx-small | h6 | xx-small text |
下面是其考虑了其自带的margin及padding后的效果:
xx-large text
x-large text
large text
medium text
small text
x-small text
xx-small text
另一种是相对大小。
- larger
- smaller
即相对于父元素的取值,而取更大或更小的值。例如,若某元素取值为larger, 如果父元素的大小值为medium,则该元素则取比medium更大一格的值,即large.
为h1指定合适的绝对值
综上,对于article header之下的h1,对应于文章标题,其font-size应为xx-large。而section之下的h1对应于章标题,应取值为x-large. section之下的section之下h1对应于节标题,应取值为large. section之section之section之下的h1对应于第2级节标题,应取值为medium.
使用dl制作文档目录
dl表示description list。它由一组name-value的组合构成。name由dt(description term)表示,value由dd(description details)表示。
例如,代码:
<dl>
<dt>Authors<dt>
<dd>John</dd>
<dd>Luke</dd>
<dt>Editor</dt>
<dd>Frank</dd>
</dl>
将产生下面的HTML渲染效果:
- Authors
- John
- Luke
- Editor
- Frank
对于每个dl之下的每个dt,都应当只有一个唯一的name与之相对应。
一般来说,dl非常适合于表示术语解释。如:
- a
- 链接
- image
- 图像
- p
- 段落
- table
- 表格
根据dl的特性,我们也可将其用于文章目录的表现媒介。
下面是一个层级较全的目录例子:
- 前言
- 第一部分 WebGL核心编程
-
- 1. WebGL概述
- 2. 快速起步
-
- 2.1 HTML5应用模板
- 2.2 最简单的WebGL应用
- 2.3 初识着色器
-
- 2.3.1 着色器的作用
- 2.3.2 着色语言简介
- 2.3.2 使用着色器
- 3. 绘制基本几何图元
-
- 3.1 绘制三角形
- 3.2 绘制多边形
- 第二部分 WebGL参考
-
- 1. WebGLRenderingContext方法
- 2. WebGLRenderingContext属性
- 第三部分 附录
- 参考资料
这是实现上面效果的HTML代码:
<dl>
<dt>前言</dt>
<dt>第一部分 WebGL核心编程</dt>
<dd>
<dl>
<dt>1. WebGL概述</dt>
<dt>2. 快速起步</dt>
<dd>
<dl>
<dt>2.1 HTML5应用模板</dt>
<dt>2.2 最简单的WebGL应用</dt>
<dt>2.3 初识着色器</dt>
<dd>
<dl>
<dt>2.3.1 着色器的作用</dt>
<dt>2.3.2 着色语言简介</dt>
<dt>2.3.2 使用着色器</dt>
</dl>
</dd>
</dl>
</dd>
<dt>3. 绘制基本几何图元</dt>
<dd>
<dl>
<dt>3.1 绘制三角形</dt>
<dt>3.2 绘制多边形</dt>
</dl>
</dd>
</dl>
</dd>
<dt>第二部分 WebGL参考</dt>
<dd>
<dl>
<dt>1. WebGLRenderingContext方法</dt>
<dt>2. WebGLRenderingContext属性</dt>
</dl>
</dd>
<dt>第三部分 附录</dt>
<dt>参考资料</dt>
</dl>
dt总是存放各级标题。使用dd作为嵌套下级内容的容器。第一级,直接添加dt,对于第一级以下的每一级,则需依序添加dd, dl, dt。
代码加亮
理解innerHTML属性
设,网页上有这样一段代码:
<p id="test">This is a <span>word</span>.</p>
则代码:
var test = document.getElementById("test");
console.log(test.textContent); // This is a word.
console.log(test.innerText); // This is a word.
console.log(test.innerHTML); // This is a <span>word</span>.
textContent及innerText均过滤掉了内部的HTML标签,只保留了文本内容。而innerHTML则将其内部的HTML标签也原封不动地保留下来。
pre的转义
先看pre中如何显示一个简单的span:This is a <span>word</span>.
我们在网页中这样写:
<pre>This is a <span>word</span>.</pre>
pre的解析流程为,保留其内部嵌套的HTML标签的含义,这里即<span>及</span>的原有含义。先将这一部分的文本提取出来,应用上相应的样式(这里并未指定任何样式)后,输出其文本内容。这样,它所显示的效果为:
This is a word.
当然,我们现在就可以为其加上一个绿色的样式:
<pre>This is a <span style="color: green;">word</span>.</pre>
现在,则显示为:
This is a word.
因此,pre保留其内部嵌套的HTML标签的意义在于,允许我们在其内部设定各种样式,以丰富网页的效果。这个也正是我们要实现源码语法加亮时想要的效果:将pre内容中相关的关键字提取出来,为其添加各种样式的HTML标签就行了。
现在的问题是,我不希望你自行解析<span>及</span>的含义,相反,你要在网页如实地输出这两个HTML标签来,这样,读者才会看到原始代码。
要做到这一点,我们需要将<span>及</span>进行转义,即用"<"代替"<"号,即用">"代替">"号。"lt"表示"less than","gt"表示"greater than",分别对应于中文中的“小于号”、“大于号”。于是,网页中的代码改为:
<pre>This is a <span>word</span>.</pre>
这样,当它在网页中显示出来时,就会显示:
This is a <span>word</span>.
这样,pre的内部代码不再出现HTML标签,而最终呈现的效果则出现了HTML标签的符号。所以,上面两行代码,第一行是我们写给计算机看的,虽然有些丑陋,但计算机看得很清楚; 而第二行代码是计算机根据这个丑陋的代码,转换为人眼更易接受的形式,以满足读者的愉悦。因此,这里有3个不同的角色,编程者必须按计算机的习惯编写丑陋的代码,而计算机自动将丑陋的代码转换成美观的效果给读者看。
转义后的pre的内容的读取与设置
网页上pre存有的内容,在未经过语法加亮前,应视为都是经过转义的。例如,<p>已经转义为<p>。
如果要在HTML网页上显示“<”,由于4个字符连在一起时才视为转义字符,则只需将第一个字符使用"&"进行转义就行了。因此,在网页中,应写:“&lt;”。
现在,我们来看看经过转义后的pre的textContent, innerText, innerHTML这3个属性值的情况。我们将6.1节中的这句话存放进一个pre中。编写内容:
<pre id="test">This is a <span>word</span>.</pre>
然后,查看相应属性值。
var test = document.getElementById("test");
console.log(test.textContent); // This is a <span>word</span>.
console.log(test.innerText); // This is a <span>word</span>.
console.log(test.innerHTML); // This is a <span>word</span>.
textContent, 及innerText属性,所取得的文本中存有HTML标签,是反转回来的代码。
而innerHTML属性,则所取得的文本中没有HTML标签,它原封不动地将pre中的内容提取给我们。这一点与6.1节中的情况正好相反。
对于这个例子,如果我们要加亮其中的HTML标签,则应在网页中这样编写:
<pre id="test">This is a <<span style="color: red;">span</span>>word</<span style="color: red;">span</span>>.</pre>
即,只要在HTML标签出现的地方,用一个拟应用样式的标签span来环绕它就行了。
var test = document.getElementById("test");
var textValue = test.innerHTML;
textValue = textValue.replace(/span/g, "<span class='tag'>$&</span>");
test.innerHTML = textValue;
这样,即可为其套上一个名为"tag"的样式。
编码约定
如同编程,在使用HTML5书写文档时,也必须遵循一定的编码约定。
| 类别 | 格式 | 例子 |
|---|---|---|
| url | 小写, 使用"-"连字符 | writing-with-html5.html |
| 标签属性 | 小写 | <span class='custspan'> |
| 函数名称 | 驼峰标记法 | function setPageSize() {} |
| 变量名称 | 驼峰标记法 | var boxWidth = 50; |
颜色原理
颜色转换
十六进制转为rgb
#FFFFFF -> rgb(255, 255, 255)
var hex = "#33FFCC";
var rgb = "rgb("
+ parseInt(hex.slice(1, 3), 16) + ","
+ parseInt(hex.slice(3, 5), 16) + ","
+ parseInt(hex.slice(5, 7), 16)
+ ")";
版面设计要求
版面设计应考虑以下因素:
- 简洁大方
- 赏心悦目
- Media Query
切忌过度花里花哨。
功夫在诗外。平时做到用心观察,用心研究,用心记录。
书写文档时一些必备功能
- ✓ 有较为合理而固定的文档结构
- ✓ 自动编排章节序号
- ✓ 自动添加文档目录及链接
- ☆ 语法加亮
- ☆ 方便地改变文章的section层级
应有的工具
- Color Wheel
- Color Representation Convertion Online
- HTML Tag Escape
- Regular Expression Online
- Unicode
- PDF, Epub Convertion
NetBeans工具助力
快速插入代码模板
我们要经常插入下面的代码:
<section class="chapter">
<h1>TITLE_HERE</h1>
<p></p>
</section>
在NetBeans中,默认情况下已有一些可快捷输入的代码块。NetBeans -> Preferences -> 编辑器 -> 代码模板 -> HTML中,可看到这些已经预定义好的代码模板。例如,若要快速地输入table,则只需输入"tab"这3个字符,然后再按一下TAB键,则可快速地输入以下代码:
<table>
<tr>
<th>Header</th>
<th>Header2</th>
</tr>
<tr>
<td>Cell</td>
<td>Cell</td>
</tr>
<tr>
<td>Cell</td>
<td>Cell</td>
</tr>
</table>
现在,我们新建自己的代码模板。在上面的界面中点击“新建”按钮,输入“sect”, 在“展开的文本中”,输入:
<section class="chapter">
<h1>${cursor}</h1>
<p></p>
</section>
在“描述”中,输入“HTML5 section”,确定。
然后,在编辑网页时,输入“sect”,再按一下“TAB”键,则可快速地输入上述内容。
利用宏将关键字转换为HTML标签
NetBeans -> Preferences -> 编辑器 -> 宏,新建,surround-with-htmltag, 输入:
caret-begin-word "<span class=\"htmltag\">" caret-end-word "</span>"
快捷键,输入“Ctrol + Command + T”。然后,圈选某个关键字,再按快捷键,则自动添加相应的HTML标签。
参考资料
浏览器
Google Chrome浏览器可以从这里直接下载。
Safari
iPhone Web SQL数据库支持
默认情况下,iPhone客户端不允许使用Web SQL. 可在iPhone上这样设置:
设置App -> Safari浏览器 -> 高级 -> Experimental Features -> Disable Web SQL
默认时,它是打开的,即默认关闭了Web SQL功能。将此开关关闭。
其他一些默认关闭的重要功能还有:
- Highlight API
- MathML Core
- WebGL 2.0
- WebGPU
可以从
设置App -> Safari浏览器 -> 高级 -> 网站数据
中看到浏览器Web SQL的使用容量情况。
在Wifi下访问开发中的网站
使用NetBeans开发Web应用时,当运行该应用时,会在Mac OSX的浏览器中加载下面的地址:
http://localhost:8383/
如果需要在iPhone中访问上述Web应用,则:
- 打开一个"终端",输入:
ifconfig, 回车。 - 找到类似于
192.168.0.103的地址。 - 在iPhone的Safari的地址栏中输入:
http://192.168.0.103/index.html
Discovery
- onLoad事件比onDOMContentLoaded事件的速度有较大的提升,尤其是第2遍以后运行,应是缓存的原因。
- Firefox的渲染速度比Safari要快
- 使用CSS3的多栏功能,Safari性能受到较大影响
- pre的overflow-x的移动端上的体验较好,但在桌面浏览器上会多出下面的滚动条
- Google Chrome: 如果在form fieldset中使用grid,则不正常。解决方案:可以使用form, 但不要使用fieldset。
Questionnaire
- Portable Doc, or Online Tutorial?
ToDo List
- 自动生成标题、自动生成目录的算法的效率有待提高
- 从各章节的标题能返回到总目录
结语
在实现这一功能的过程中,我的感悟是,并不需要多高深的知识,也并不需要多先进的工具,只有一点:细节决定成败。
只要设定好目标,在向其迈进的过程中,不要害怕会遇到各种各样的问题,这是避免不了的。但应认真分析为何出现这类问题,潜下心来思考如何解决,或化大为小,或化繁为简,或化难为易,终能实现目标。