Javascript DOM编程艺术读书笔记9

第9章 CSS-DOM

  • 网页由一下三层信息构成一个共同体:结构层、表示层、行为层
  • 只有把CSS style属性插入到标记里,才可以用DOM style属性去查询这些信息。放在style.css或者写在文件部分里的<style>标签里,都没有用。

根据元素在节点树里的位置来设置样式

查找<h1>元素后面的元素,设置成加粗。

1
2
3
4
5
6
7
8
├─story.html

├─scripts
│ addLoadEvent.js
│ styleHeaderSiblings.js

└─styles
format.css

story.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>Man bites dog</title>
<script type="text/javascript" src="scripts/addLoadEvent.js"></script>
<script type="text/javascript" src="scripts/styleHeaderSiblings.js"></script>
<link rel="stylesheet" type="text/css" media="screen" href="styles/format.css"/>
</head>
<body>
<h1>Hold the front page</h1>
<p>This first paragraph leads you in.</p>
<p>Now you get the nitty-gritty of the story.</p>
<p>The most important information is delivered first.</p>
<h1>Extra! Extra!</h1>
<p>Further developments are unfolding.</p>
<p>You can read all about it here.</p>
</body>
</html>

addLoadEvent.js

1
2
3
4
5
6
7
8
9
10
11
function addLoadEvent(func) {
var oldonload = window.onload;
if (typeof window.onload != 'function') {
window.onload = func;
} else {
window.onload = function() {
oldonload();
func();
}
}
}

styleHeaderSiblings.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
46
47
48
function styleHeaderSiblings(){
if(!document.getElementsByTagName) return false;
var headers=document.getElementsByTagName("h1");
var elem;
for(var i=0;i<headers.length;i++){
elem=getNextElement(headers[i].nextSibling);
addClass(elem,"intro");
}
}

function getNextElement(node){
//如果这个节点是元素节点就返回这个节点
if(node.nodeType==1){
return node;
}
//如果这个节点不是元素节点,就继续寻找下一个节点
if(node.nextSibling){
return getNextElement(node.nextSibling);
}
return null;
}
//以下两种是更通用的方法
function addClass(element,value) {
//检查className属性的值是否为null
if (!element.className) {
//如果是把新的class设置值直接赋值给className
element.className = value;
} else {
//如果不是,就把一个空格和新的calss设置值追加到className属性上去
newClassName = element.className;
newClassName+= " ";
newClassName+= value;
element.className = newClassName;
}
}
function styleElementSiblings(tag,theclass){
if(!document.getElementsByTagName)return false;
var elems=document.getElementsByTagName(tag);
var elem;
for(var i=0;i<elems.length ;i++){
elem=getNextElement(elems[i].nextSibling);
addClass(elem,theclass);
}
}
//addLoadEvent(styleHeaderSiblings);
addLoadEvent(function(){
styleElementSiblings("h1","intro")
})

format.css

1
2
3
4
.intro {
font-weight: bold;
font-size: 1.2em;
}

根据某种条件反复设置某种样式

将表格中奇数行和偶数行的背景颜色设置成不同的

1
2
3
4
5
6
7
8
9
10
│  itinerary.html

├─scripts
│ addLoadEvent.js
│ displayAbbreviations.js
│ highlightRows.js
│ stripeTables.js

└─styles
format.css

itinerary.html

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>Cities</title>
<link rel="stylesheet" type="text/css" media="screen" href="styles/format.css" />
<script type="text/javascript" src="scripts/addLoadEvent.js"></script>
<script type="text/javascript" src="scripts/stripeTables.js"></script>
<script type="text/javascript" src="scripts/displayAbbreviations.js"></script>
<script type="text/javascript" src="scripts/highlightRows.js"></script>
</head>
<body>
<table>
<caption>Itinerary</caption>
<thead>
<tr>
<th>When</th>
<th>Where</th>
</tr>
</thead>
<tbody>
<tr>
<td>June 9th</td>
<td>Portland, <abbr title="Oregon">OR</abbr></td>
</tr>
<tr>
<td>June 10th</td>
<td>Seattle, <abbr title="Washington">WA</abbr></td>
</tr>
<tr>
<td>June 12th</td>
<td>Sacramento, <abbr title="California">CA</abbr></td>
</tr>
</tbody>
</table>
</body>
</html>

addLoadEvent.js

1
2
3
4
5
6
7
8
9
10
11
function 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
function displayAbbreviations() {
if (!document.getElementsByTagName || !document.createElement || !document.createTextNode) return false;
// 得到所有"abbr"元素
var abbreviations = document.getElementsByTagName("abbr");
if (abbreviations.length < 1) return false;
var defs = new Array();
// 循环遍历
for (var i=0; i<abbreviations.length; i++) {
var current_abbr = abbreviations[i];
if (current_abbr.childNodes.length < 1) continue;
var definition = current_abbr.getAttribute("title");
var key = current_abbr.lastChild.nodeValue;
defs[key] = definition;
}
// 创建一个dl列表
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);
}
if (dlist.childNodes.length < 1) return false;
// 创建一个标题
var header = document.createElement("h2");
var header_text = document.createTextNode("Abbreviations");
header.appendChild(header_text);
// 添加标题和列表到html页面上
document.body.appendChild(header);
document.body.appendChild(dlist);
}
addLoadEvent(displayAbbreviations);

highlightRows.js:鼠标指针悬停在某个表格行的上方时,把该文本加黑加粗

1
2
3
4
5
6
7
8
9
10
11
12
13
function highlightRows() {
if(!document.getElementsByTagName) return false;
var rows = document.getElementsByTagName("tr");
for (var i=0; i<rows.length; i++) {
rows[i].onmouseover = function() {
this.style.fontWeight = "bold";
}
rows[i].onmouseout = function() {
this.style.fontWeight = "normal";
}
}
}
addLoadEvent(highlightRows);

stripeTables.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
function stripeTables() {
if(!document.getElementsByTagName) return false;
//找出文档中的所有table元素
var tables=document.getElementsByTagName("table");
var odd,rows;
for(var i=0;i<tables.length;i++){
//对每个table元素,创建odd变量并把它初始化为false
odd=false;
//遍历表格中的所有数据行
rows=tables[i].getElementsByTagName("tr");
for(var j=0;j<rows.length;j++){
//如果变量odd的值是true,设置样式并把odd变量修改为false
if(odd==true){
addClass(rows[j],"odd");
odd=false;
}else{
//如果变量odd的值是false,不设置样式,但把odd变量修改为true
odd=true;
}
}
}
}

function addClass(element,value) {
//检查className属性的值是否为null
if (!element.className) {
//如果是把新的class设置值直接赋值给className
element.className = value;
} else {
//如果不是,就把一个空格和新的calss设置值追加到className属性上去
newClassName = element.className;
newClassName+= " ";
newClassName+= value;
element.className = newClassName;
}
}
addLoadEvent(stripeTables);

ClassName

  • 问题:在DOM直接设置或修改样式,让行为层干表示层的活,并不是理想的工作方式。
  • 解决方法:为元素追加一个className,在css文档中含有该类名的样式。可以通过修改CSS中类名的样式修改样式而不需要修改JS函数。
1
2
3
4
5
6
7
8
9
10
11
12
13
function addClass(element,value) {
//检查className属性的值是否为null
if (!element.className) {
//如果是把新的class设置值直接赋值给className
element.className = value;
} else {
//如果不是,就把一个空格和新的calss设置值追加到className属性上去
newClassName = element.className;
newClassName+= " ";
newClassName+= value;
element.className = newClassName;
}
}