本章内容梳理自 《JavaScript DOM编程艺术》
1. DOM
什么是DOM?
简单来说,DOM是一套对文档的内容进行抽象和概念化的方法。
W3C对DOM的定义是:一个与系统平台和编程语言无关的接口,程序和脚本可以通过这个接口动态地访问和修改文档的内容,结构和样式。
2. JavaScript语法
-
JavaScript必须通过HTML/XHTML文档才能执行,有两种方式可以做到这点:
- 放到文档head标签里面的script标签之间
- 将JavaScript代码存为一个扩展名为.js的独立文件,并将src指向该文件
更好的做法是把script标签放在HTML文档的最后,body标签之前。这样能使浏览器更快加载页面
-
JavaScript是解释性程序设计语言,不需要编译器 (和Java, C++等不同)。所以JavaScript没有编译阶段,代码中的错误只能等到解释器执行到有关代码的时候才能发现。
注释
- 在HTML中,注释为
<!-- 这是注释 -->
JavaScript解释器对<!--和对//的处理的是一样的,但是会将-->视为注释的一部分,尽量不要在JavaScript中使用<!--进行注释!
赋值
JavaScript允许直接对变量赋值而无需事先声明。
但是如果不声明,比如 a = 1, 会创建或者改动a这个全局变量,有可能会造成污染。
数据类型
字符串,数值,布尔值,数组, 对象
数组声明:
var arr = Array();var arr = Array(4);var arr = Array("John", "Paul", "George", "Ringo");var arr = ["John", "Paul", "George", "Ringo"];
对象声明:
- var obj = Object()
- var obj = {name: "xxx", age: xx}
比较操作符
== 并非全等
例子:
var a = false var b = "" console.log(a == b) // Output: true
变量的作用域
在定义函数的时候,最好使用const / var而不是 直接改动全局变量,这样会很安全
3. DOM
文档: DOM中的D
document对象代表着HTML文档
对象:DOM中的O
- 用户自定对象: 由程序员自己创建的对象
- 内建对象: 内建在JavaScript语言里的对象,如Array,Math和Date等
- 宿主对象:由浏览器提供的对象
其中,最基础的对象是window对象。window对象对应着浏览器本身,这个对象的属性,这个对象的属性和方法统称为BOM,包括window.blur, window.open等方法
模型:DOM中的M
DOM把一份文档标识为一棵树,更具体地说,DOM把文档标识为一棵节点树。
节点
先介绍三种节点: 元素节点(<p>, <div>, <ul等),文本节点(像<p>中包含的hello)和属性节点(像<p>中包含的title="xxx")。
CSS
对样式的声明既可以放在文档的<head>标签里,也可以放在另外一个样式表文件里。
继承: 节点数上的各个元素将继承父元素的样式属性。
获取元素
有三种DOM方法可以获取元素节点,分别是通过元素ID,标签名字和通过类名字来获取。
1. getElementById
将返回一个对象,这个对象对应着document对象里Id为xx的元素。
typeof操作符可以告诉我们它的操作数是一个字符串,数值,函数,布尔值还是对象。
object instanceof constructor用来判断constructor的prototype属性是否出现在object的圆形链上
2. getElementsByTagName
- 将返回一个对象数组,每个对象分别对应着document对象中的一个标签为xx的元素。
- getElementsByTagName允许使用通配符,比如
document.getElementsByTagName('*')可以返回文档里所有的元素节点
可以搭配getElementById来使用,比如document.getElementById('ul').getElementByTagName('*')就可以获得所有ul的子元素节点
3. getElementsByClassName
- HTML5中新增的方法,返回一个数组,该数组包含所有包含该元素类名的元素,其中元素类名可以包含多个,将会匹配所有同时包含这些类名的元素
- 比如
document.getElementsByClassName('important sale')就会返回一个所有同时包含important和sale类名的数组 - 但是因为可能不是所有浏览器都支持,所以为了弥补,需要自己编写getElementsByClassName函数:
funciton getElementsByClassName(node, className) {
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;
}
}
获取和设置属性
getAttribute
.getAttribute(xx)是一个函数,它的参数为你要查找的属性名字,返回值为属性的内容。如果没有属性,将会返回null
setAttribute
- setAttribute()允许我们设置属性的内容,比如:
obj.setAttribute(attrName, attrVal)将会设置属性名为attrName的的值为attrVal。 - 假设我们设置了一个p节点的属性title为currTitle,这个并不会反映在项目的原文件中。这是DOM的工作模式:先加载文档的静态内容,再动态刷新,动态刷新不影响文档的静态内容。这是DOM的真正威力: 对页面内容进行刷新却不需要在浏览器里面刷新页面。
4. JavaScript实践 - 图片库
可以用以下函数来实现点击切换页面中图片内容的效果:
<a href="xx/xx.jpg" onclick="showPic(this);return false"></a>
<script>
function showPic(whichpic) {
var source = whichpic.getAttribute("href");
var placeholder = document.getElementById("placeholder");
placeholder.setAttribute("src", source);
}
</script>
其中,return false的原因是: 事件处理函数的机制是: 在给某个元素添加了时间处理函数之后,一旦事件发生,相应的JavaScript代码就会执行。被调用的函数可以返回一个值,这个值将被传递给那个事件处理函数。如果返回值为true,那么onclick这个事件处理函数就会认为被点击了;如果返回值为false,那么onclick就会认为没有被点击。避免了<a>元素默认的跳转功能。
childNodes属性
- 可以用来获取任何一个元素的所有子元素节点。包含所有类型的元素节点,包括元素节点,属性节点,文本节点等。每个节点都有nodeType属性,但是它的值不是英文。
- 元素节点的nodeType为1
- 属性节点的nodeType为2
- 文本节点的nodeType为3
window.onload
会在页面加载时执行。 window.onload=countBodyChildren;可以在页面加载时执行这个函数。
nodeValue属性
如果想改变一个文本节点的值,可以使用DOM提供的nodeValue属性,它用来得到一个节点的值。
比如<p id="ptag">hello</p>,要获得hello这个值,得用document.getElementById("ptag").childNodes[0].nodeValue
同时要设置的话直接.childNodes[0].nodeValue = xxx
firstChild & lastChild
等价于childNodes[0] 和 childNodes[node.childNodes.length - 1]