DOM编程
一、什么是DOM编程?
文档对象模型 (DOM) 是HTML和XML文档的编程接口。它提供了对文档的结构化的表述,并定义了一种方式可以使从程序中对该结构进行访问,从而改变文档的结构,样式和内容。DOM 将文档解析为一个由节点和对象(包含属性和方法的对象)组成的结构集合。简言之,它会将web页面和脚本或程序语言连接起来。简单来说:DOM编程就是使用document对象的API完成对网页HTML文档进行动态修改,以实现网页数据和样式动态变化效果的编程.
二、什么是document?
document对象代表整个html文档,可用来访问页面中的所有元素,是最复杂的一个dom对象,可以说是学习好dom编程的关键所在。
三、document对象如何获取?
document对象是window对象的一个成员属性,通过window.document来访问,当然也可以直接使用document,根据HTML代码结构特点,document对象本身是一种树形结构的文档对象。

四、DOM节点分类node
结点对象:Node,document对象中的每一个分支点都是一个node对象,它有三个子类
- 元素节点 Element 如:<a href="链接地址">我的链接</a>
- 属性节点 Attribute 如:href="链接地址"
- 文本节点 Text 如:我的链接
五、DOM操作的内容
- 查询元素(获取元素,进而操作元素,或者元素的属性,文本)
- 操作文本
- 操作属性
- 操作元素
- 操作CSS样式(一个特殊的属性style)
六、Node节点常用的属性和方法
1.属性
1.1 Node.prototype.nodeType
document.nodeType // 9
不同节点的nodeType的属性值不同
- 文档节点(document):9,对应常量Node.DOCUMENT_NODE
- 元素节点(element):1,对应常量Node.ELEMENT_NODE
- 属性节点(attr):2,对应常量Node.ATTRIBUTE_NODE
- 文本节点(text):3,对应常量Node.TEXT_NODE
- 文档片断节点(DocumentFragment):11,对应常量Node.DOCUMENT_FRAGMENT_NODE
- 文档类型节点(DocumentType):10,对应常量Node.DOCUMENT_TYPE_NODE
- 注释节点(Comment):8,对应常量Node.COMMENT_NODE
1.2 Node.prototype.nodeName
nodeName属性返回节点的名称
let div = document.getElementById('d1');
div.nodeName // "DIV"
不同节点的nodeName属性值不同
- 文档节点(document):#document
- 元素节点(element):大写的标签名
- 属性节点(attr):属性的名称
- 文本节点(text):#text
- 文档片断节点(DocumentFragment):#document-fragment
- 文档类型节点(DocumentType):文档的类型
- 注释节点(Comment):#comment
1.3 Node.prototype.nodeValue
nodeValue属性返回一个字符串,表示当前节点本身的文本值,该属性可读写
只有文本节点(text)、注释节点(comment)和属性节点(attr)有文本值,其他类型的节点一律返回null
// <div id="d1">hello world</div> var div = document.getElementById('d1'); div.nodeValue // null div.firstChild.nodeValue // "hello world"
textContent属性返回当前节点和它的所有后代节点的文本内容
// <div id="box">This is <span>some</span> text</div> document.getElementById('box').textContent // This is some text
textContent属性会自动忽略节点内部的HTML标签,返回所有文本内容
该属性是可读写的,设置属性的值,会用一个新的文本节点替换掉所有原来的子节点
该属性会自动对HTML 标签转义
document.getElementById('box').textContent = '<p>GoodBye!</p>';
1.5 Node.prototype.ownerDocument
Node.ownerDocument属性返回当前节点所在的顶层文档对象,即document对象
let div = d1.ownerDocument
console.log(div === document) //True
document对象本身的ownerDocument属性,返回null
1.6 Node.prototype.nextSibling
Node.nextSibling属性返回紧跟在当前节点后面的第一个节点,如果没有节点返回null
// <div id="d1">hello</div><div id="d2">world</div> var d1 = document.getElementById('d1'); var d2 = document.getElementById('d2'); d1.nextSibling === d2 // true
该属性还包括文本节点和注释节点,如果节点后面有空格,该属性会返回一个文本节点
1.7 Node.prototype.previousSibling
previousSibling属性返回当前节点前面的、距离最近的一个节点。如果当前节点前面没有节点,返回null
// <div id="d1">hello</div><div id="d2">world</div> var d1 = document.getElementById('d1'); var d2 = document.getElementById('d2'); d2.previousSibling === d1 // true
该属性还包括文本节点和注释节点,如果节点前面有空格,该属性会返回一个文本节点
1.8 Node.prototype.parentNode
parentNode属性返回当前节点的父节点
对于一个节点,他的父元素只可能是三种元素:元素节点,文档节点和文档片段节点
let div = document.getElementById("d1")
div.parentNode.removeChild(div)
上面代码,用过div.parentNode属性将div元素删除,文档节点和文档片段节点的父节点都是null
1.9 Node.prototype.parentElement
parentElement属性返回当前节点的父元素节点。如果当前节点没有父节点,或者父节点类型不是元素节点,则返回null
1.10 Node.prototype.firstChild,Node.prototype.lastChild
firstChild属性返回当前节点的第一个子节点,如果当前节点没有子节点,则返回null。
// <p id="p1"><span>First span</span></p> var p1 = document.getElementById('p1'); p1.firstChild.nodeName // "SPAN"
firstChild返回的除了元素节点,还可能是文本节点或注释节点
// <p id="p1"> // <span>First span</span> // </p> var p1 = document.getElementById('p1'); p1.firstChild.nodeName // "#text"
p元素和span元素之间有换行,所以firstChild返回的是文本节点
lastChild属性返回当前节点的最后一个子节点,如果当前节点没有子节点,则返回null。用法与firstChild属性相同
1.11Node.prototype.childNodes
childNodes属性返回一个类似数组的对象(NodeList集合),成员包括当前节点的所有子节点。
var children = document.querySelector('ul').childNodes;
//children就是ul元素的所有子节点
该属性可以遍历某个节点的所有子节点
let div = document.getElementById("d1") let Child = div.childNodes for(let i = 0; i< Child.length; i++){ //... }
除了元素节点,childNodes属性的返回值还包括文本节点和注释节点
如果当前节点不包括任何子节点,则返回一个空的NodeList集合
NodeList对象是一个动态集合,一旦子节点发生变化,立刻会反映在返回结果之中。
1.12 Node.prototype.isConnected
isConnected属性返回一个布尔值,表示当前节点是否在文档之中
var test = document.createElement('p');
test.isConnected // false
document.body.appendChild(test);
test.isConnected // true
test节点是生成的节点,没有插入文档之前 isConnected返回的是False,插入之后返回True
2.方法
2.1 Node.prototype.appendChild()
appendChild()方法接受一个节点对象作为参数,将其作为最后一个子节点,插入当前节点,该方法的返回值就是插入文档的子节点
|
1
2 |
var p = document.createElement('p');
document.body.appendChild(p); |
新建一个节点,插入body的尾部如果参数节点是已经存在的节点,appendChild方法会将其从原来的位置移动到新的位置
2.2 Node.prototype.hasChildNodes()
hasChildNodes方法返回一个布尔值,表示当前节点是否有子节点
let div = document.getElementById("box")
if(div.hasAttributes()){
div.removeChild(div.childNodes[0])
}
如果div节点有子节点,那么就移出第一个子节点,子节点包括所有类型的节点,不仅仅是元素节点。只包含一个空格,hasChildNodes方法也会返回true
判断节点有没有子节点的方法
- node.hasChildNodes()
- node.firstChild !== null
- node.childNodes && node.childNodes.length > 0
2.3 Node.prototype.cloneNode()
loneNode方法用于克隆一个节点 它接受一个布尔值作为参数,表示是否同时克隆子节点.它的返回值是一个克隆出来的新节点
let newDiv = document.querySelector('div').cloneNode(true);
- 该方法返回的节点不在文档之中,即没有任何父节点,必须使用诸如Node.appendChild这样的方法添加到文档之中
- 克隆一个节点,会拷贝该节点的所有属性,但会丢失事件方法
2.4 Node.prototype.insertBefore()
insertBefore方法用于将某个节点插入父节点内部的指定位置
接受两个参数
- 第一个参数是所要插入的节点
- 第二个参数是父节点内部的一个子节点
- 新节点将插入到这个节点的前面,返回值是插入的新节点
var p = document.createElement('p');
document.body.insertBefore(p, document.body.firstChild);
新建一个节点,插在document.body.firstChild的前面,节点就成为document.body的第一个子节点。如果insertBefore方法的第二个参数为null,则新节点将插在当前节点内部的最后位置,变成最后一个子节点。
var p = document.createElement('p');
document.body.insertBefore(p, null);
2.5 Node.prototype.removeChild()
removeChild方法接受一个子节点作为参数,用于从当前节点移除该子节点。返回值是移除的子节点
var div = document.getElementById('box');
div.parentNode.removeChild(div);
注意,removeChild方法是在div父节点上调用的,不是在dib节点上调用的,如果参数节点不是当前节点的子节点,removeChild方法将报错。
2.6 Node.prototype.replaceChild()
replaceChild方法用于将一个新的节点,替换当前节点的某一个子节点
var replacedNode = parentNode.replaceChild(newChild, oldChild);
- newChild是用来替换的新节点
- oldChild是将要替换走的子节点
- 返回值是被替换的节点oldChild。
2.7 Node.prototype.isEqualNode(),Node.prototype.isSameNode()
isEqualNode方法返回一个布尔值,用于检查两个节点是否相等,相等的节点指的是两个节点的类型,属性,子节点相同
var p1 = document.createElement('p');
var p2 = document.createElement('p');
p1.isEqualNode(p2) // true
isSameNode方法返回一个布尔值,表示两个节点是否为同一个节点
var p1 = document.createElement('p');
var p2 = document.createElement('p');
p1.isSameNode(p2) // false
p1.isSameNode(p1) // true
2.8 Node.prototype.normalize()
normalize方法用于清理当前节点内部的所有文本节点,它会去除空的文本节点,并且将响铃的文本节点合并成一个
var div = document.createElement('div');
div.appendChild(document.createTextNode('Part 1 '));
div.appendChild(document.createTextNode('Part 2 '));
div.childNodes.length // 2
div.normalize();
div.childNodes.length // 1
七、直接获取节点的几种方式
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>直接获取子节点</title> <script type="text/javascript"> function fun1(){ //根据id获取元素 var element01 = document.getElementById('d1') //获取元素的文本属性 console.log(element01.innerText) } function fun2(classname){ //根据class属性获取元素 var elements = document.getElementsByClassName(classname) for(var i=0;i<elements.length;i++){ console.log(elements[i].innerText) } } function fun3(){ //根据标签名获取标签对象。多个属性放在数组中 var elements = document.getElementsByTagName('input') for(var i=0;i<elements.length;i++){ console.log(elements[i]) } } function fun4(){ //根据name属性的值获取 var elements = document.getElementsByName('hobby') for(var i=0;i<elements.length;i++){ console.log(elements[i]) } } </script> </head> <body> <div id='d1' class="a">这是第一个div</div> <div id='d2' class="a">这是第二个div</div> <div id='d3' class="a">这是第三个div</div> <input id='i1' class="a" name='name1'/> <div id='d4' class="b" name='name1'>这是第四个div</div> <div id='d5' class="b">这是第五个div</div> 爱好: <input type="checkbox" name="hobby" value="1" />篮球 <input type="checkbox" name="hobby" value="2" />足球 <input type="checkbox" name="hobby" value="3" />羽毛球 <hr /> <input type="button" value="id值获取" onclick='fun1()' /> <input type="button" value="class属性值获取" onclick='fun2("a")' /> <input type="button" value="标签名获取" onclick='fun3()' /> <input type="button" value="name属性值获取" onclick='fun4()' /> </body> </html>
八、操作节点属性
<!doctype html> <html> <head> <meta charset="utf-8"> <title></title> <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" /> <link href="css/mui.css" rel="stylesheet" /> <script type="text/javascript"> function func1(){ var element = document.getElementById('in1') /* //方式一: 获取: 节点.属性名 修改:节点.属性名=属性值 console.log(element.type) console.log(element.value) //修改 属性的值 element.type = 'button' element.value = '真的很好' */ //方式二: console.log(element.getAttribute('type')) console.log(element.getAttribute('value')) element.setAttribute('type', 'button') element.setAttribute('value', '你好他好') } </script> </head> <body> <input type="text" id="in1" value="你好呀" /> <hr > <input type="button" value="改变" onclick="func1()" /> </body> </html>
九、操作节点样式
通过style.css样式名和通过设置class属性两种方式实现
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script type="text/javascript"> function func1(){ var node = document.getElementById('div1') //方式一: /* node.style.width = '200px' node.style.height = '200px' node.style.border = '10px solid royalblue' */ //方式二:给节点添加一个class属性,值设置为a node.setAttribute('class','a' ) } </script> <style type="text/css"> #div1{ width: 100px; height: 100px; border: 1px solid red; } .a{ background-color: #6495ED; color: blanchedalmond; font-size: 50px; } </style> </head> <body> <div id="div1"> 你好呀 </div> <input type="button" value="测试" onclick="func1()"/> </body> </html>
十、操作标签文本
- innerHtml 操作双标签中间的HTML
- innerText 操作双标签中间的 Text
- value 操作表单标签值
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <style type="text/css"> #d1{ border: #6495ED; width: 100px; height: 100px; } </style> <script type="text/javascript"> function func01(){ var node = document.getElementById('d1') //获取文字 //console.log(node.innerHTML) //方式一:将文字信息 包含span标签,和缩进都获取回来了 console.log(node.innerText) // 方式二 a 文字 b 只能获取文字信息 var element = document.getElementById('i1') console.log(element.value) } function func02(){ var node = document.getElementById('d1') //方式一: // node.innerText = '<h1>竹杖芒鞋轻胜马</h1>'、 //方式二: node.innerHTML = '<h1>竹杖芒鞋轻胜马</h1>' //修改内容 var element = document.getElementById('i1') element.value = '无敌了' //修改input标签中value属性的值 } </script> </head> <body> <div id="d1"> a <span>文字</span> b </div> <input type="text" id="i1" value="暮霭程程楚天阔" /> <input type="button" value="获取内容" onclick="func01()"/> <input type="button" value="修改内容" onclick="func02()"/> </body> </html>
十一、增加和删除节点
- 创建元素createElement()
- 增加元素appendChild()
- 删除元素removeChild()
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>增加删除</title> <style type="text/css"> #d1{ border: 1px solid #FF0000; width: 400px; height: 200px; } </style> <script type="text/javascript"> function fun1(){ var div01 = document.getElementById('d1'); //创建 一个input标签 var username = document.createElement('input') //给标签设置属性 username.setAttribute('type', 'text'); username.setAttribute('value', '请输入内容'); //将创建好的input标签指定给div01 div01.appendChild(username); //创建一个密码框 var password = document.createElement('input') //设置属性 password.setAttribute('type', 'password') password.setAttribute('value', '请输入密码') //将标签添加给div01 div01.appendChild(password) //创建删除按钮 var del = document.createElement('input') //设置属性 del.setAttribute('type', 'button'); del.setAttribute('value','删除') del.onclick = function f1(){ alert('即将删除') //删除元素 div01.removeChild(username) div01.removeChild(password) div01.removeChild(del) div01.removeChild(br) } //添加给div01 div01.appendChild(del) //添加一个换行标签 var br = document.createElement('br') div01.appendChild(br) } </script> </head> <body> <div id="d1"> </div> <input type="button" value="增加" onclick="fun1()" /> </body> </html>
十一、案例练习
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <style type="text/css"> #outerdiv{ width: 200px; height: 200px; border: #6495ED; background-color: gray; text-align: center; margin-top: 200px; margin-left: 200px; } #outerdiv input{ width: 50px; height: 50px; margin: 20px; } </style> <script type="text/javascript"> function func2(){ alert('嘿嘿嘿!!!') } function func1(){ //获取元素 var d = document.getElementById('outerdiv'); //通过随机数设置宽和高 var left = Math.floor(Math.random()*1000); var top = Math.floor(Math.random()*500); //修改元素的左边距、上边距 d.style.marginTop = top + 'px'; d.style.marginLeft = left + 'px'; } </script> </head> <body> <div id="outerdiv"> <h3>dou you love me?</h3> <input type="button" value="是" onclick="func2()"/> <input type="button" value="否" onmousemove="func1()"/> </div> </body> </html>

浙公网安备 33010602011771号