DOM概述
JavaScript的三个组成部分:核心(ECMAScript欧洲计算机制造商协会,描述了JS的语法和基本对象),文档对象模型(DOM,把整个HTML当成一个对象,处理网页内容的方法和接口),浏览器对象模型(BOM,把浏览器当成一个对象,与浏览器交互的方法和接口)
什么是DOM和节点
DOM(文档对象模型)
DOM为文档提供了结构化表示,并定义了如何通过脚本来访问文档结构。其实就是为了能让js操作html元素而制定的一个规范。
DOM树状的树形结构
节点
由上面的结构图可以看出,整个文档就是一个文档节点,每个HTML标签都是一个元素节点,标签中的文字则是文本节点,标签的属性是属性节点,一切都是节点...
获取节点
直接获取
有三种方法:
通过id: document.getElementById('box')
返回值是一个元素节点,可以直接使用(例如获得属性值,设置属性等)。如果查找不到对应id名的节点,返回值为null而不是undefined。
通过标签名: document.getElementsByTagName('div')
通过类名: document.getElementsByClassName('box') (在IE5,6,7,8中不兼容)
通过标签名和类名获得的返回值是一个伪数组,习惯性是惯例之后再使用。查找不到对应的节点,返回值为空数组。获取其中第一个元素,是 document.getElementsByTagName('div')[0]
通过访问关系获取
节点的访问关系,是以属性的方式存在的。
节点并不是孤立的,因此可以通过DOM节点之间的相对关系对它们进行访问。
父节点 | 兄弟节点 | 子节点 | 所有子节点 |
parentNode | nextSibling | firstChild | childNodes |
nextElementSibling | firstElementChild | children | |
previousSibling | lastChild | ||
previousElementSibling | lastElementChild |
(1)父节点
parentNode
(2)兄弟节点
nextSibling:调用者是节点。IE678中指下一个元素节点(标签),火狐谷歌IE9+以后都指下一个节点(包括空文档和换行节点)。所以在IE678中用nextSlibling,在火狐谷歌IE9+中用nextElementSibling。
下一个兄弟节点 = 节点.nextElementSibling || 节点.nextSibling
previousSibling:指上一个兄弟节点。同nextSibling兼容相同
上一个兄弟节点 = 节点.previousElementSibling || 节点.previousSibling
(3)单个子节点
firstChild:调用者是父节点。IE678指第一个子元素节点(标签),火狐谷歌IE9+以后都指的是第一个节点(包括空文档和换行节点)。firstElementChild在火狐谷歌IE9+指第一个元素节点。
第一个子节点 = 节点.firstElementChild || 节点.firstChild
lastChild:最后一个子节点。与firstChild兼容性相同。
最后一个子节点 = 节点.lastElementChild || 节点.lastChild
(3)所有子节点
childNodes:返回指定元素的子节点集合,包含所有节点。
children:返回指定元素的子节点集合,只包含元素节点。它是非标准属性,在IE678中,包含注释节点。
节点操作
创建节点
document.createElement()
插入节点
父节点.appendChild()
<div id="box"></div> <script> //创建节点li var liNode = document.createElement('li'); //获取父元素 var box = document.getElementById('box'); //添加 box.appendChild(liNode); </script>
父节点.insertBefore()
<div id="box"> <span></span> <span id="span"></span> <span></span> </div> <script> //创建节点li var liNode = document.createElement('li'); //获取父元素 var box = document.getElementById('box'); var span = document.getElementById('span'); //将新创建的节点添加到#span前 box.insertBefore(liNode, span); </script>
删除节点
父节点.removeChild()
<div id="box"> <span></span> <span id="span"></span> <span></span> </div> <script>//获取父元素 var box = document.getElementById('box'); var span = document.getElementById('span'); //删除#span节点 box.removeChild(span); </script>
或者可以只查找自己本身来删除本身
<script> //获取自身元素 var span = document.getElementById('span'); //删除#span节点 span.parentNode.removeChild(span); </script>
复制节点
oldNode.cloneNode(true)。
接受一个布尔值参数,true表示深复制(复制节点及其所有子节点),false表示浅复制(复制节点本身,不复制子节点)。谁调用复制谁。
属性操作
通过元素.属性名或者元素[属性名]
<img src="./1.png" alt="图片" title="图片1" id="img1" class="image"> <script> var img = document.getElementById('img1'); console.log(img.src); console.log(img['src']); console.log(img.className); console.log(img['className']); </script>
通过getAttribute,setAttribute和removeAttribute操作
<img src="./1.png" alt="图片" title="图片1" id="img1" class="image"> <script> var img = document.getElementById('img1'); //获取 console.log(img.getAttribute('id')); //设置 img.setAttribute('id', 'img2'); //删除 img.removeAttribute('alt'); </script>
这两个方法的区别是,前者操作的是DOM对象本身,后者操作的是标签本身。例如通过点方法添加一个'aaa'属性,就不能在html中展示出来,但是能获取到。通过setAttribute方法添加,就会在html结构中展示出来并能获取到。