JavaScript系列之操作DOM对象/面向对象
01 操作DOM对象
-
DOM : Document Object Model ( 文档对象模型 )
由于HTML文档被浏览器解析后就是一棵DOM树,要改变HTML的结构,就需要通过JavaScript来操作DOM。
-
获取DOM节点
-
在操作一个DOM节点之前,先要获取到这个DOM节点。最常用的方法有
document.getElementById()
document.getElementsByTagName()
,以及CSS选择器document.getElementsByClassName()
。 -
document.getElementById()
可以直接定位唯一的一个DOM节点。document.getElementsByTagName()
和document.getElementsByClassName()
总是返回一组DOM节点。要精确地选择DOM,可以先定位父节点,再从父节点开始选择,以缩小范围。
-
-
节点属性
parentNode //返回节点的父节点 childNodes //返回子节点集合 childNodes[i]//返回子节点集合中的i个节点 firstChild//返回节点的第一个子节点,最普遍的用法是访问该元素的文本节点 lastChild //返回节点的最后一个子节点 nextSibling //下一个节点 previousSibling//上一个节点
-
元素属性
firstElementChild // 返回节点的第一个子节点,最普遍的用法是访问该元 素的文本节点 lastElementChild //返回节点的最后一个子节点 nextElementSibling //下一个节点 previousElementSibling //上一个节点
-
更新DOM
拿到一个DOM节点后,我们可以对它进行更新。
-
更新节点的文本有两种办法:
- 修改innerHTML属性,这个方式非常强大,不但可以修改一个DOM节点的文本内容,还可以直接通过HTML片段修改DOM节点内部的子树。
- 修改innerText或textContent属性,但是该方式无法设置任何HTML标签。
-
更新CSS样式的方法:
- DOM节点的
style
属性对应所有的CSS,可以直接获取或设置。
//先获取节点ele,再通过style属性更新CSS样式 ele.style.fontsize = '50px';
- DOM节点的
-
- 插入DOM
- 先获取一个DOM节点,如果该DOM节点为空,例如,
<div></div>
,那么,直接使用innerHTML = <span>child</span>
就可以修改DOM节点的内容,相当于“插入”了新的DOM节点。 - 如果这个DOM节点不是空的,有以下两种方式进行插入
A.appendChild(B)
,把B节点添加到A节点的最后一个子节点。insertBefore( A,B )
,把A节点插入到B节点之前
- 先获取一个DOM节点,如果该DOM节点为空,例如,
- 创建DOM
createElement( tagName)
, 创建一个标签名为tagName的新元素节点.
-
删除DOM
-
要删除一个节点,首先要获得该节点本身以及它的父节点,然后,调用父节点的
removeChild
把自己删掉。// 获取想要移除的节点: var self = document.getElementById('to-be-removed'); // 获取待移除节点的父节点: var parent = self.parentElement; // 删除: var removed = parent.removeChild(self); //注意事项:删除后的节点虽然不在文档树中了,但其实它还在内存中,可以随时再次被添加到别的位置。
-
-
替换DOM
-
要替换一个节点,首先要获得该节点本身以及它的父节点,然后,调用父节点的
replaceChild
把自己替换掉。// 获取想要替换的节点: var old = document.getElementById('to-be-replaced'); // 获取待移除节点的父节点: var parent = self.parentElement; // 创建新的节点 var new=document.createElement("img"); // 给新节点设置属性 new.setAttribute("src","images/f03.jpg"); // 替换: parent.replaceChild(new,old);
-
02 面向对象
JavaScript不区分类和实例的概念,而是通过原型(prototype)来实现面向对象编程。
-
创建对象
- 方式1:通过new Object();
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <script> //创建一个对象,通过new Object(); var person = new Object(); //给对象设置属性 对象.属性名 = 属性值; person.name = "John"; person.age = 18; person.sex = '男'; //给对象设置方法 对象.方法名 = function(){}; person.showName = function () { alert(this.name); }; //调用方法 person.showName(); </script> </body> </html>
- 方式2:使用花括号
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <script> //使用花括号定义一个对象 //注意点: //1.使用冒号赋值 //2.多个属性之间使用逗号隔开 //3.最后一个属性或者方法不需要加逗号; var student = { name:"John", age:20, sex:'男', showName:function () { document.write(this.name) } }; console.log(student); </script> </body> </html>
- 方式3:使用构造函数(构造函数的首字母必须大写)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <script> //使用构造函数创建多个同类型的对象 function person(name,age,sex) { this.name = name; this.age = age; this.sex = sex; this.showName = function () { alert(this.name) } } var student1 = new person("John",23,'男'); var student2 = new person("Snow",24,'女'); var student3 = new person("Lily",25,'女'); console.log(student1); console.log(student2); console.log(student3); </script> </body> </html>
-
原型对象
- JavaScript对每个创建的对象都会设置一个原型,指向它的原型对象。
当我们用
obj.xxx
访问一个对象的属性时,JavaScript引擎先在当前对象上查找该属性,如果没有找到,就到其原型对象上找,如果还没有找到,就一直上溯到Object.prototype
对象,最后,如果还没有找到,就只能返回undefined
。- 每个函数都有一个prototype属性,这个属性是一个指针,可以将一个对象的原型指向一个对象。
- 以创建对象方式三中的代码为例,用
new Person()
创建的对象还从原型上获得了一个constructor
属性,它指向函数Student
本身,它的原型链如下:
student1 ↘ student2 -→ Person.prototype ----> Object.prototype ----> null student3 ↗
- 如果我们通过
new Person()
创建了很多对象,这些对象的showName
函数实际上只需要共享同一个函数就可以了,这样可以节省很多内存。要让创建的对象共享一个showName
函数,根据对象的属性查找原则,我们只要把showName
函数移动到student1
、student2
这些对象共同的原型上就可以了,也就是Person.prototype
.修改代码如下:
function person(name,age,sex) { this.name = name; this.age = age; this.sex = sex } } Person.prototype.showName = function () { alert(this.name); };
-
原型继承
一个原型对象是另一个原型对象的实例。相关的原型对象层层递进,就构成了实例与原型的链条,就是原型链。
JavaScript的原型继承实现方式就是:
- 定义新的构造函数,并在内部用
call()
调用希望“继承”的构造函数,并绑定this
; - 借助中间函数
F
实现原型链继承,最好通过封装的inherits
函数完成; - 继续在新的构造函数的原型上定义新方法。
- 定义新的构造函数,并在内部用