CSS-DOM
网页是由三层信息构成的共同体:
- 结构层—HTML负责
- 行为层—JavaScript负责
- 表示层—CSS负责
可以通过DOM改变结构层,那么也可以通过DOM来改变表示层。先看一段代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Example</title>
</head>
<body>
<h1 id="example" style="color: grey; font-family: 'Arial',sans-serif;">
An example of a paragraph
</h1>
</body>
</html>
刚开始为h1标签设置了自己的CSS样式,想把这个网页变得花里胡哨一点,比如说当鼠标放在文本字段上时希望字体能更换颜色。这时就可以利用DOM来改变CSS样式:
<script>
window.onload = function(){
example = document.getElementById("example");
/*鼠标放在文本段时会触发*/
example.onmouseover = function() {
example.style.color = "black";
}
}
</script>
定位到h1标签再改变style属性的color值。这里的style
属性是一个对象。把这段脚本添加到title标签下就可以了(也可以保存为一个文件再引入)。
虽然这样可以通过DOM来改变样式,但是如果想更换另一种字体颜色的话就只有通过更改Javascript脚本来实现。这样会导致行为层和表示层的之间的关系会有些含糊。利用DOM来改变样式的本意是通过DOM来改变样式,但是样式的具体内容还是需要CSS来设置,DOM只是提供了一个更改样式的方法。
可以利用class属性来作为DOM和CSS的中间人。
利用DOM来为某个标签的class属性赋值,至于class属性的具体内容就交给CSS好了。
举个例子:
利用DOM把每段黑体字下面的第一行的字体颜色变大:
可以先在CSS文件里这样写:
.intro {
font-weight: bold;
font-size: 1.2em;
}
之后,利用DOM改变目标元素的class属性:
function styleHeaderSiblings() {
if(!document.getElementsByTagName) return false;
var headers = document.getElementsByTagName("h1");
var elem;
for(var i=0; i<headers.length; i++) {
elem = getNextSibling(headers[i].nextSibling);
elem.className = "intro";
}
}
/*要找的是节点,如果不是节点就利用递归函数继续找。找到的话返回节点,找不到的话返回null。*/
function getNextSibling(node) {
if(node.nodeType == 1) {
return node;
}
if(node.nextSibling){
return getNextSibling(node.nextSibling);
}
return null;
}
这样如果想改变font-weight
或者font-size
就只需要更改CSS脚本而不必更改Javascript脚本。
但是这样有一个弊端,更改后的class属性会替换原先的class属性。
未更改前:
<p class="odd">This first paragraph leads you in.</P>
如果利用DOM更改class属性那么p标签会变成下面这样:
<p class="new">This first paragraph leads you in.</P>
解决方案,利用字符串拼接的方法把更改后的class属性值既包含更改前的又有更改后的:
<p class="old new">This first paragraph leads you in.</P>
那么脚本要相应的改成这样:
function styleHeaderSiblings() {
if(!document.getElementsByTagName) return false;
var headers = document.getElementsByTagName("h1");
var elem;
for(var i=0; i<headers.length; i++) {
elem = getNextSibling(headers[i].nextSibling);
elem.className = "intro";
}
}
function getNextSibling(node) {
if(node.nodeType == 1) {
return node;
}
if(node.nextSibling){
return getNextSibling(node.nextSibling);
}
return null;
}
/*拼接字符串用拼接后的字符串作为class属性值*/
function addClass(elem, value) {
if(!elem.className) {
elem.className = value;
} else {
newClassName = elem.className;
newClassName += ' ';
newClassName += value;
elem.className = newClassName;
}
}
本文的第一个例子对应的是example1.html,第二个例子对应的是story.html,在github中还有一个例子对应的是itinerary.html 。