R·ex / Zeng


音游狗、安全狗、攻城狮、业余设计师、段子手、苦学日语的少年。 MUGer, hacker, developer, amateur UI designer, punster, Japanese learner.

网页编程心得:语义元素 & 结构、样式和行为的分离

注意:本文发布于 3054 天前,文章中的一些内容可能已经过时。

绝大部分的 HTML 标签是有语义的。例如 <p>(paragraph)表示段落,<a>(anchor)表示锚,<abbr>(abbreviation)表示缩写。

为什么要有语义?这是显然的,因为 HTML 是用来描述网页文档的一种语言,我说“这里有个标题”,那么 HTML 中应该就是用 <h1> 标签把标题括起来。

有同学会问,我把某个 <p> 的文字样式调成加粗、大号字,不是照样能显示出标题效果吗?整个网页都用 <p>,抛弃大量难记忆的语义标签,岂不是很好的一件事?对于这个问题,只能说提问的同学是站在人的角度上看问题的。网页不光是给人看的,搜索引擎、生成网页摘要的软件、屏幕阅读器等等也要看。而它们看到的,并不是绚丽的图形,而是一行行代码。因此,如果不显式在代码中说明一个元素的语义,它们就会纠结。而一旦说明语义,它们就能为人们提供更好的服务。

早期的网页大多是用 Table 布局,Table 布局的特点是:代码量大,语义不明确。一开始的网页主要是用来学术交流,就是简单的文档而已。随着互联网的发展,人们对网页的美观度要求越来越高,聪明的人们想到了用表格来布局网页,并很快成为了潮流。但是,表格毕竟只是用于显示数据的。W3C 组织推出了 CSS 来解决网页布局的问题,但是 Table 布局已经在人们头脑中根深蒂固,因此并没有退出历史舞台。直到近几年,情况才有所扭转,CSS 布局的时代来临了!

记得以前看一些开发者社区的帖子,发帖时间大概是 09 年至 11 年吧,人们一直在争论究竟是 Table 布局好还是 DIV+CSS 布局好。我个人当然是推荐后者,但是看帖子里说的“DIV+CSS 可以精简代码,将样式与结构分离”,觉得说的并不完全正确,因为 Table 也可以用 CSS,也可以实现分离。我个人的观点是,DIV+CSS 的使用,使得在 HTML 中完全不用考虑布局问题,可以专心地使用语义标签让文档内容丰富多彩,而真正的样式则在 CSS 中得到体现。如果只是使用了 CSS,但并不注重语义,那么这就跟 Table 布局没什么区别了。我的个人意见是:先写完 HTML,然后尝试添加 CSS。

浏览器会给语义标签一定的默认样式,也就是说,只要 HTML 写得好,就算不给网页加 CSS,网页的内容也会有相当好的可读性。W3C 的官网就是相当好的一个例子,大家可以试着将网页中的 CSS 去掉,然后随意感受一下其良好的可读性。理论上说,只有当语义标签没法满足需求的时候,才应该去考虑 <div><span> 这两个无语义的标签。

至于 JavaScript,比较好的办法也是将其与 HTML 文档分隔开。我们完全可以将标签的 onclick 属性去掉,取而代之的则是在 window.onload 中添加事件绑定。这是 QT 的做法,在网页中也可以这么做。这样,我们就把 HTML、CSS、JavaScript 分成了不同的文件(或者同一文件中完全无关的模块)。

啰嗦了这么多,该上个例子了。

<form action="..." method="...">
    <div style="color:#09F">我是标题</div>
    <p>
        <span style="font-weight:bold">用户名</span>
        <input type="text" name="username" id="username">
    </p>
    <p>
        <span style="font-weight:bold">密码</span>
        <input type="password" name="password" id="password">
    </p>
    <input type="text" id="txt_input" onchange="parse(this)">
    <input type="submit" id="btn_submit" onclick="md5(this)" value="不要点我">
</form>

就这么一段代码,将文档内容、样式、JavaScript 代码完全融合在了一起,维护起来会是比较困难的。可以把它改成下面的样子。

<form action="..." method="...">
    <fieldset>
        <legend>我是标题</legend>
        <p>
            <label for="username">用户名</label>
            <input type="text" name="username" id="username">
        </p>
        <p>
            <label for="password">密码</label>
            <input type="password" name="password" id="password">
        </p>
        <input type="text" id="txt_input">
        <input type="submit" id="btn_submit" value="不要点我">
    </fieldset>
</form>
form legend {
    color: #09F;
}
form label {
    font-weight: bold;
}
window.onload = function () {
    // 获取元素
    var txtInput = document.getELementById("txt_input");
    var btnSubmit = document.getElementById("btn_input");
    // 事件绑定
    txtInput.onchange = parse(txtInput);
    btnSubmit.onclick = md5(btnSubmit);
}

此外,为了用户体验良好,推荐 CSS 引入要放在文件起始位置,JavaScript 引入要放在文件末尾。这样浏览器会先加载样式表,再加载文档主体,最后加载 JavaScript 代码。这样避免了文档身子(HTML)出来了衣服(CSS)还在后面的尴尬,也防止了因为 JavaScript 文件过大而网页加载中长时间白屏。

P.S.这个思想是我最近才有的,目前我写的项目很少有这个思想的体现,但是我觉得它非常好,以后的项目中也会逐渐往这方面靠拢。

版权声明:除文章开头有特殊声明的情况外,所有文章均可在遵从 CC BY 4.0 协议的情况下转载。
上一篇: 让SVG做背景,可随元素大小而变化
下一篇: 换一种思路给Sublime-Text配置编译器

这是我们共同度过的

第 2635 天