JavaScript DOM 编程艺术(读书笔记一)

前言

     时隔两年,第二次看这本书《JavaScript DOM 编程艺术》,依稀记得这是接触到的第一本关于 JS 的书,当初看的时候似懂非懂,现在,再次捧起来,翻一翻,温故知新,下面将罗列一些书中的知识点。

getElementsByClassName

     对文档里的信息进行检索时有 getElementByIdgetElementsByTagName 等函数,然而,通过类名来检索也是我们迫切需要的函数之一,虽然 HTML5 DOM 中已经新增了 getElementsByClassName,让我们可以通过 class 属性来访问元素,然而,只有比较新的浏览器才支持它,因此,可以使用已有的DOM方法来实现 getElementsByClassName 函数,使之在较老的浏览器中照样可以使用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function getElementsByClassName(classname, node) {
node = node || document;
//将第二个参数默认值改为document,node表示DOM树中的搜索起点
if(node.getElementsByClassName) {
return node.getElementsByClassName(classname);
}else {

var results = new array();
var elems = node.getElementsByTagName("*");
for(var i=0; i<elems.length; i++) {
if(elems[i].className.indexOf(classname) != -1){
results[results.length] = elems[i];
}
}
return results;
}
}

     以上代码跟书本上给的代码稍有不同,改了两处地方,一是把两个参数的位置互换,二是添加了代码node = node || document;,添加该行代码的作用是把搜索起点的默认值设为 document 注1,两处的修改作用是使该函数跟 HTML5 DOM 提供的函数一样,进行函数调用的时候支持getElementsByClass(class)的形式。
     看书看着看着,发现也可以通过检查 class 属性的方法来访问元素.

1
2
3
4
5
6
7
8
9
10
11
function getClassByAttribute(classname, node) {
node = node || document;
var results = new Array();
var items = document.getElementsByTagName("*");
for(var i=0; i<items.length; i++){
if(items[i].getAttribute("class") == classname){
results[results.length] = items[i];
}
}
return results;
}

setAttribute

     我们可以通过 setAttribute对属性节点的值作出修改,例如:document.getElementById(“main”).setAttribute(“title”,”news”),然而,对文档作出修改后,查看源代码时看到的仍是修改前的属性值,该现象源于 DOM 的工作模式,先加载文档的静态内容,再动态刷新,动态刷新不影响文档的静态内容。

取消链接 a 的默认行为

     我们有时在给 a 标签添加 onclick 事件时,并不希望出发到链接的默认跳转行为,此时,可以通过下面的添加return false方法来实现。

1
2
3
4
<a href="http://www.baidu.com" onclick="code...;return false;">
百度
</a>
//点击之后不会跳转到百度

     在实际应用开发中,并不建议将此处出现的事件处理注2的 JavaScript 代码(即onclick处)嵌在 HTML 代码中,此处只是为了演示方便,在实际开发中,应该将结构、表示和行为分开,分别将表示层和行为层的代码放在外部文件中通过外链的方式引入。

常见的三种 DOM 节点(每个节点都是一个对象)
  1. 元素节点,其nodeTyoe属性值是1;
  2. 文本节点,其nodeTyoe属性值是2;
  3. 属性节点,其nodeTyoe属性值是3。
childNodes

     我们可以通过 childNodes 来获取任何一个元素的所有子节点(只是子节点,孙子节点不算),子节点包括了文本节点和元素节点,值得注意的是换行符也算文本节点,而块级元素都会换行,因此每个块元素前后都会存在换行这类文本节点。

平稳退化

     平稳退化的作用,就是可以让访问者在他们的浏览器不支持 JavaScript 的情况下仍能顺利地浏览网站,也就是说虽然某些功能无法使用,但最基本的操作仍能顺利完成,下面是一些平稳退化的例子。

1
2
3
4
5
6
7
//该函数的作用是打开一个新窗口"popup"
function popUp(winURL) {
window.open(winURL,"popup","width=300,height=480");
}
<a href="http://www.example.com/" onclick="popUp(this.href);return false;">
Example
</a>

     上述 JavaScript 代码的本意是当点击链接 Example 时,在新的窗口 popup 中显示 http://www.example.com/的内容,但当浏览器不支持 JavaScript 或是 JavaScript 被禁用时,该链接还是起作用的,只是变成在当前窗口中显示内容,但至少不影响到基本的操作,这便是平稳退化了。
     其实,现在不支持 JavaScript 的浏览器很少很少,浏览 Web 时同时禁用图像和 JavaScript 的用户也非常少见,那平稳退化是不是没有必要呢?其实不然,有一个非常重要的访问者,恰恰不太能理解 JavaScript 代码,该访问者便是搜索机器人,搜索机器人是一种自动化的程序,它们浏览Web的目的是为了把各种网页加到搜索引擎的数据库里,各大搜索引擎都有类似的程序,但是只有极少数搜索机器人能够理解JavaScript代码,所以,如果JavaScript网页不能平稳退化,它们在搜索引擎上的排名就可能大受损害。
     外链的 CSS 其实也是平稳退化,这是 CSS 技术的优点,文档结构与文档样式的分离,具备CSS支持的浏览器固然可以把网页呈现得美轮美奂,不支持或禁用CSS功能的浏览器同样可以把网页的内容按照正确的结构显示出来,实现了平稳退化。

对象检测

     对象检测的作用是检查浏览器对 JavaScript 的支持程度,如果不理解则中途退出,保证了“古老”的浏览器不会因为脚本代码而出问题,可以像下面这样进行检测。

1
2
3
4
window.onload = function() {
if(!document.getElementsByTagName) return false;
js code...
}

未完待续 ^_~

注1:对于node = node || document,我们可以直到,当”||”运算符前的node为true时,该运算的结果为node,否则结果为document,而我们一般调用该函数时的形式为getElementsByClassName(class),省略了第二个参数,因此可以将搜索起点的默认值设为document。
注2:事件处理函数,其作用是在特定事件发生时调用特定的 JavaScript 代码,例如在点击的时候显示弹出框,此处的点击事件便是事件处理函数。