第8章 充实文档的内容
两项重要原则:
- 渐进增强:应该总是从最核心的部分,也就是从内容开始逐步加强
 - 平稳退化:缺乏必要的CSS和JS支持的访问者也可以访问到核心内容
 
充实文档的基本思路
用JS函数先把文档结构里的一些现有信息提取出来,再把哪些信息以一种清晰和有意义的方式插入到文档中去。比如下面编写的几个函数:
- displayAbbreviations.js:把文档里的缩略语显示为一个“缩略语”列表
 - displayCitations.js:把文档里引用的每段文献节选生成一个“文献来源链接”
 - displsyAccesskeys.js:把一个元素与键盘上的某个特定按键关联在一起
 

1  | ├─explanation.html  | 
explanation.html
1  | 
  | 
addLoadEvent.js1
2
3
4
5
6
7
8
9
10
11function addLoadEvent(func) {
  var oldonload = window.onload;
  if (typeof window.onload != 'function') {
    window.onload = func;
  } else {
    window.onload = function() {
      oldonload();
      func();
    }
  }
}
displayAbbreviations.js:把文档里的缩略语显示为一个“缩略语”列表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
38
39
40
41
42
43
44
45
46function displayAbbreviations() {
    if (!document.getElementsByTagName || !document.createElement || !document.createTextNode) return false;
    //取得所有缩略词
    var abbrevistions = document.getElementsByTagName("abbr");
    //判断是否有abbr元素
    if (abbrevistions.length < 1) return false;
    var defs = new Array();
    //遍历这些缩略词
    for (var i = 0; i < abbrevistions.length; i++) {
        var current_abbr = abbrevistions[i];
        //在IE浏览器中的平稳退化,如果当前元素没有子节点,就会立刻开始下一次循环。因为IE浏览器在统计abbr元素的子节点的个数时总会返回一个错误的值0.
        if(current_abbr.childNodes.length<1)continue;
        var definition = current_abbr.getAttribute("title");
        //文本节点是元素内部的第一个也是最后一个节点,即唯一节点
        var key = current_abbr.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);
    }
    //ie浏览器的defs数组是空的,就不会创建出任何dt和dd元素,如果dl没有任何子节点,就立刻退出该函数
    if(dlist.childNodes.length<1) return false;
    //创建标题
    var header = document.createElement("h2");
    var header_text = document.createTextNode("Abbreviations");
    header.appendChild(header_text);
    //把标题添加到页面主体
    document.body.appendChild(header);
    //把定义列表添加到页面主体
    document.body.appendChild(dlist);
}
addLoadEvent(displayAbbreviations);
displayCitations.js:把文档里引用的每段文献节选生成一个“文献来源链接”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
30function displayCitations(){
    if(!document.getElementsByTagName||!document.createElement||!document.createTextNode) return false;
    //取得所有的引用
    var quotes=document.getElementsByTagName("blockquote");
    //遍历引用
    for(var i=0;i<quotes.length;i++){
        //如果该节点没有cite属性,就立刻跳到下一个循环
        if(!quotes[i].getAttribute("cite")){
            continue;
        }
        //保存cite属性
        var url=quotes[i].getAttribute("cite");
        //取得引用中的所有元素节点的固定用法,不能直接quites[i].lastChild因为最后一个子节点可能是换行符之类,而不是最后一个元素节点
        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);
displsyAccesskeys.js:把一个元素与键盘上的某个特定按键关联在一起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
38
39
40
41
42
43
function displayAccesskeys(){
    if(!document.getElementsByTagName||!document.createElement||!document.createTextNode)return false;
    //取得文档中的所有链接
    var links=document.getElementsByTagName("a");
    //创建一个数组,保存访问键
    var akeys=new Array();
    //遍历链接
    for(var i=0;i<links.length;i++){
        var current_link=links[i];
        //如果没有accesskey属性,就继续下一个循环
        if(!current_link.getAttribute("accesskey"))continue;
        //取得accesskey的值
        var key=current_link.getAttribute("accesskey");
        //取得链接文本
        var text=current_link.lastChild.nodeValue;
        //添加到数组
        akeys[key]=text;
    }
    //创建列表
    var list=document.createElement("ul");
    //遍历访问键
    for(key in akeys){
        var text=akeys[key];
        //创建放到列表项中的字符串
        var str=key+":"+text;
        //创建列表项
        var item=document.createElement("li");
        var item_text=document.createTextNode(str);
        item.appendChild(item_text);
        //把列表项添加到列表中
        list.appendChild(item);
    }
    //创建标题
    var header=document.createElement("h3");
    var header_text=document.createTextNode("Accesskeys");
    header.appendChild(header_text);
    //把标题添加到页面主体
    document.body.appendChild(header);
    //把列表添加到页面主体
    document.body.appendChild(list);
}
addLoadEvent(displayAccesskeys);
typography.css1
2
3
4
5
6
7
8
9body {
  font-family: "Helvetica","Arial",sans-serif;
  font-size: 10pt;
}
abbr {
  text-decoration: none;
  border: 0;
  font-style: normal;
}