充实文档的内容

不应该做什么

理论上,你可以用JavaScript把一些重要的内容添加到网页上。事实上这是一个坏主意,因为这样一来JavaScript就没有任何空间去平稳退化。那些缺乏必要的JavaScript支持的访问者就会永远看不到你的重要内容。至少到现在为止,各大搜素引擎网站的搜索机器人还几乎不支持JavaScript。

最佳实践中,我们要牢记下面这两项原则:

  • 渐进增强。渐进增强原则基于这样一种思想:你应该总是从最核心的部分,也就是从内容开始。应该根据内容使用标记实现良好的结构;然后再逐步加强这些内容。这些增强工作既可以是通过CSS改进呈现效果,也可以是通过DOM添加各种行为。

  • 平稳退化。渐进增强的实现必然支持平稳退化。如果你按照渐进增强的原则去充实内容,你为内容添加的样式和行为就自然支持平稳退化,那些缺乏必要的CSS和DOM支持的访问者仍可以访问到你的核心内容。

把“不可见”变成“可见”

绝大多数属性的内容(即属性值)在web浏览器里都是不显示的,只有极少数属性例外,但不同的浏览器在呈现这些例外的属性时却常常千姿百态。比如说,有些浏览器会把title属性的内容显示为弹出式的提示框,另一些浏览器则会把它们显示在状态栏里。在显示属性这个问题上,你只能听任浏览器的摆布。其实只需要一点点DOM编程,我们就能够把这种控制器重新掌握在自己的手里。本文着眼于使用DOM技术为网页添加一些使用的小部件。

  • 得到隐藏在属性里的信息。

  • 创建标记封装这些信息。

  • 把这些标记插入到文档。

内容

内容:

What is the Document Object Model?
The W3C defines the DOM as: 
A platform- and language-neutral interface that will allow programs and scripts to dynamically acess and update the content,structure and style of documents.
It is an API that can be used to navigate HTML and XML documents.

添加标记:

<h1>What is the Document Object Model?</h1>
<p>
  The <abbr title="World Wide Web Consortium">W3C</abbr> defines the <abbr title="Document Object Model">DOM</abbr> as:
</p>
<blockquote cite="http://www.w3.org/DOM/">
  <p>
     A platform- and language-neutral interface that will allow programs and scripts to dynamically acess and update the content,structure and style of documents.
  </p>
</blockquote>
<p>
  It is an <abbr title="Application Programming Interface">API</abbr> that can be used to navigate <abbr title="HyperText Markup Language">HTML</abbr> and <abbr title="eXtensible Markup Language">XML</abbr> documents.
</p>

选用HTML、XHTML还是HTML5

对于标记而言,选用HTML还是XHTML是你的自由。重要的是不管选用的哪种文档类型,你使用的标记必须与你选用的DOCTYPE声明一致。 HTML5文档类型声明:

<!DOCTYPE html>

而且这个文档声明同样也支持HTML和XHTML标记。 下面是按照HTML5规范完成的最终标记文件explanation.html:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Explaining the Document Object Model</title>
</head>
<body>
  <h1>What is the Document Object Model?</h1>
<p>
  The <abbr title="World Wide Web Consortium">W3C</abbr> defines the <abbr title="Document Object Model">DOM</abbr> as:
</p>
<blockquote cite="http://www.w3.org/DOM/">
  <p>
     A platform- and language-neutral interface that will allow programs and scripts to dynamically acess and update the content,structure and style of documents.
  </p>
</blockquote>
<p>
  It is an <abbr title="Application Programming Interface">API</abbr> that can be used to navigate <abbr title="HyperText Markup Language">HTML</abbr> and <abbr title="eXtensible Markup Language">XML</abbr> documents.
</p>
</body>
</html>

CSS

把下面样式表保存到typography.css文件,并将其放到子目录styles中。

body {
			font-family:"Helvetica","Arial",sans-serif;
			font-size:10pt;
		}
abbr {
			text-decoration:none;
			boder:0;
			font-style:normal;
		}

JavaScript

有些浏览器会在你把鼠标指针悬停在缩略语上时,将它的title属性显示为一个弹出式的提示消息。就像浏览器所使用的默认样式一样,浏览器对缩略语的默认呈现行为也是各有各的做法。就像我们可以用自己的CSS样式表去取代浏览器所使用的默认样式那样,你也可以用DOM去改变浏览器的默认行为。

显示“缩略语列表”

将<abbr>标签中的title属性集中显示在一个页面: 定义列表:

<dl>
  <dt>W3C</dt>
  <dd>World Wide Web Consortium</dd>
  <dt>DOM</dt>
  <dd>Document Object Model</dd>
  <dt>API</dt>
  <dd>Application Programming Interface</dd>
  <dt>HTML</dt>
  <dd>HyperText Markup Language</dd>
  <dt>XML</dt>
  <dd>eXtensible Markup Language</dd>
</dl>

编写displayAbbreviations函数

具体步骤: 1.遍历这份文档的所有abbr元素。 2.保存每个abbr元素的title属性。 3.保存每个abbr元素包含的文本。 4.创建一个“定义列表”元素(即dl元素)。 5.遍历刚才保存的title属性和abbr元素的文本。 6.创建一个“定义标题”元素(即dt元素)。 7.把abbr元素的文本插入到这个dt元素。 8.创建一个“定义描述”元素(即dd元素)。 9.把title属性插入到这个dd元素。 10.把dt元素追加到第4步创建的dl元素上。 11.把dd元素追加到第4步创建的dl元素上。 12.把dl元素追加到explanation.html文档的body元素上。

var abbreviations=document.getElementsByTagName("abbr");
var defs=new Array();
for(var i=0;i<abbreviations.length;i++){
		var definition=abbreviations[i].getAttribute("title");
		var key=abbreviations[i].lastChild.nodeValue;     //firstChild也可以,但若文本本<em>包含则只能用lastChild
		defs[key]=definition;         //将key用作数组元素的下标
	}

创建标记

var dlist=document.createElement("dl");
for(key in defs){           //含义:对于defs关联数组里的每个键,把它的值赋给变量key
		var definition=defs[key];
		var dtitle=document.createElement("dt");
		var dtitle_text=document.createTextNode(key);
		dtitle.appendChild(dtitle_text);
		var ddesc=document.createElement("dd");
		var ddesc_text=document.createTextNode(definition);
		ddesc.appendChild(ddesc_text);
		dlist.appendChild(dtitle);
		dlist.appendChild(ddesc);
	}

插入这个定义列表

创建一个描述性标题并将它们插入文档中。 displayAbbreviations()函数代码:

function displayAbbreviations(){
		var abbreviations=document.getElementsByTagName("abbr");
		var defs=new Array();
		for(var i=0;i<abbreviations.length;i++){
				var definition=abbreviations[i].getAttribute("title");
				var key=abbreviations[i].lastChild.nodeValue;     
				defs[key]=definition;        
		}
		var dlist=document.createElement("dl");
		for(key in defs){           
				var definition=defs[key];
				var dtitle=document.createElement("dt");
				var dtitle_text=document.createTextNode(key);
				dtitle.appendChild(dtitle_text);
				var ddesc=document.createElement("dd");
				var ddesc_text=document.createTextNode(definition);
				ddesc.appendChild(ddesc_text);
				dlist.appendChild(dtitle);
				dlist.appendChild(ddesc);
		}
		var header=document.createElement("h2");
		var header_text=document.createTextNode("Abbreviations");
		header.appendChild(header_text);
		document.body.appendChild(header);
		document.body.appendChild(dlist);
	}

检查兼容性

函数用到了getElementsByTagName、createElement和createTextNode:

if(!document.getElementsByTagName) return false;
if(!document.createElement) return false;
if(!document.createTextNode) return false;

显示“文献来源链接表”

blockquote元素包含一个属性cite。这是一个可选属性,你可以给它一个URL地址,告诉人们blockquote元素的内容引自哪里。但在实践中,浏览器会完全忽视cite属性的存在。利用JavaScript语言和DOM,我们完全可以把那些信息收集起来,并以一种更有意义的方式把它们显示在网页上。步骤如下: 1.遍历这个文档里所有blockquote元素。 2.从blockquote元素提取出cite属性的值。 3.创建一个标识文本是source的链接。 4.把这个链接赋值为blockquote元素的cite属性值。 5.把这个链接插入到文献节选的末尾。

编写displayCitations函数

遍历并提取cite属性值:

var quotes=document.getElementsByTagName("blockquote");
for(var i=0;i<quotes.length;i++){
		if(!quotes[i].getAttribute("cite")){
						continue;      //跳到下一次循环
				}
		var url=quotes[i].getAttribute("cite");
	}

查找你的元素

把“文献来源链接”放在blockquote元素所包含的最后一个子元素节点之后,直接想到的是用lastChild属性,可是在</p>标签和</blockquote>标签之间还存在着一个换行符,有些浏览器会把这个换行符解释为一个文本节点。但可以通过把通配符“*”作为参数传递给getElementsByTagName方法,它会把所有的元素一一返回给我们。

var quoteChildren=quotes[i].getElementsByTagName("*");
if(quoteChildren.length<1) continue;
var elem=quoteChildren[quoteChildren.length-1];

创建链接

var link=document.createElement("a");
var link_text=document.createTextNode("source");
link.appendChild(link_text);
link.setAttribute("href",url);

插入链接

var superscript=document.createElement("sup");
superscript.appendChild(link);     //呈现上标的效果
elem.appendChild(superscript);

代码清单

function displayCitations(){
		if(!document.getElementsByTagName) return false;
		if(!document.createElement) return false;
		if(!document.createTextNode) return false;
		var quotes=document.getElementsByTagName("blockquote");
		for(var i=0;i<quotes.length;i++){
			if(!quotes[i].getAttribute("cite")){
					continue;      
				}
			var url=quotes[i].getAttribute("cite");
			var quoteChildren=quotes[i].getElementsByTagName("*");
			if(quoteChildren.length<1) continue;
			var elem=quoteChildren[quoteChildren.length-1];
			var link=document.createElement("a");
			var link_text=document.createTextNode("source");
			link.appendChild(link_text);
			link.setAttribute("href",url);
			var superscript=document.createElement("sup");
			superscript.appendChild(link);     
			elem.appendChild(superscript);
		}
	}
addLoadEvent(displayCitations);

Last updated