什么是DOM?
DOM 是Document Object Model 的缩写,是对XML文档的内容进行表示的模型。它把XML文档看做是一系列node节点间的关系,并且把每一个node都当做一个对象,所以叫文档对象模型。
DOM还提供了一系列的API,是允许添加、编辑、移动、删除DOM树种任意位置的节点的,从而创建了一个引用程序。
在网页中,我们可以把DOM理解为不仅是对网页中各个元素关系的描述(把每个元素或文本都视为一个节点,即node,关系是指每个节点之间是兄弟关系还是父子关系等等),并且还可以把每个网页元素或者一段文字,都当成一个可操作的对象。比如说:html元素和body元素是父节点与子节点的关系。body下的某个div和span又是什么关系等等。
获取DOM节点
1、通过document获取
API | 说明 |
getElementById | 通过元素ID获取节点: document.getElementById(元素ID名) |
getElementByName | 通过元素的name属性获取节点: document.getElementByName(元素name属性) |
getElementByTagName | 通过元素的标签名获取节点: document.getElementByTagName(元素标签) 它返回的都nodeList对象 |
getElementByClassName | 通过类名获取节点: getElementByClassName(元素类名) [IE6/7/8不支持] |
querySelector | 获取一个DOM元素: document.querySelector(任意选择器) [IE8及以上] |
querySelectorAll | 获取一组DOM元素: document.querySelectorAll(任意选择器)[IE8及以上] |
2、通过节点指针获取
节点属性表:
API | 名称 | 说明 |
Node | 节点 | DOM定义的node接口,js中所有的节点类型均继承自node类型 |
nodeValue | 节点值 | Text节点或document节点的文本内容,可进行读写操作 |
nodeName | 节点名称 | 元素的标签名,以大写形式表示 |
nodeType | 节点类型 | 表示该节点的类型 |
childNodes | 子节点 | 每个节点都有childNodes属性,它是只读的类数组对象,实时动态的保存该节点的子节点 |
children | 子节点 | children只包含element元素,它的功能和childNodes类似,不同的是children是非标准属性,由IE提出的,在某些浏览器中不兼容 |
nodeList | 节点列表 | nodeList是类数组对象,用于动态的保存一组有序的节点 |
parentNode | 父节点 | 该节点的父节点,但类似document这样的对象没有父节点,它的parentNode属性为null |
previousSibling | 上一个兄弟节点 | 该节点的兄弟节点中的上一个,和该节点具有相同的父节点 |
nextSibling | 下一个兄弟节点 | 该节点的兄弟节点中的下一个,其中,具有相同的父节点的两个节点成为兄弟节点 |
firstChild | 第一个子节点 | 该节点的子节点的第一个节点,该节点没有子节点则为null |
lastChild | 最后一个节点 | 该节点的子节点的最后一个节点,该机诶单没有子节点则为null |
节点信息表:
API | 名称 | nodeType | nodeName | nodeValue |
Element | 元素 | 1 | 元素的标签名 | null |
Attribute | 属性 | 2 | 属性的名称 | 属性值 |
Text | 文本 | 3 | #text | 节点内包含的文本 |
Comment | 注释 | 8 | #comment | 注释的内容 |
Document | 文档 | 9 | #document | null |
Fragment | 文档碎片 | 11 | #document-fragment | null |
操作DOM节点
1、创建节点
createElement()
此方法可创建元素节点,返回的是一个Element节点,具有指定的标签名。创建出来的新元素节点不会被自动添加到文档里,既然没有添加到文档里,说明它还是一个游离的状态,所以它也没有nodeParent属性。如果想把它添加到文档里,可使用appendChild() 或 insertBefore() 或 replaceChild() 方法。
document.createElement();
let oDiv = document.createElement('div');
document.body.appendChild(oDiv);
createAttribute() 和 createTextNode()
createAttribute()方法用于创建一个新的Attribute节点,给元素添加属性。createTextNode() 是用于创建一个文本节点,所以nodeType等于3,如下边的hello.nodeName将返回#text。和createElement()一样,用createTextNode() 创建的节点也不会自动添加到文档里。需要使用appendChild() 或 insertBefore() 方法或 replaceChild() 方法。它经常与createElement() 配合使用。
let oDiv = document.createElement('div');
oDiv.setAttribute('title', 'my demo');
document.body.appendChild(oDiv);
// 如果需要添加文字,则需要createTextNode()这个方法了
let hello = document.createTextNode('hello world');
let container = document.createElement('div');
container.appendChild(hello);
document.body.appendChild(container);
注意:一定要理解好元素节点与文本节点的区别。元素节点是没有nodeValue的,只有文本节点才有nodeValue。在IE9以下浏览器中,回车换行不算一个文本节点,但标准浏览器中这是个文本节点。
createFragment()
此方法用于创建文档片段,虽然不能把文档片段直接添加到文档中,但是它可以作为一个‘仓库’来使用,将可能需要添加到文档中的节点保存在这里,需要添加时可以一次性将需要添加的节点添加到文档中,避免浏览器的反复渲染,提高性能。
let oFragment = document.createDocumentFragment();
let ul = document.getElementById('list');
let oLi = null;
for(let i = 0; i < 10; i++) {
oLi = document.createElement('li');
oLi.appendChild(document.createTextNode('item' + (i + 1)));
oFragment.appendChild(oLi);
};
ul.appendChild(oFragment);
2、插入节点
appendChild()
在指定元素节点的最后一个子节点之后添加节点,需要注意的是,该方法返回的是新的子节点。它经常跟createElement() 和 createTextNode()、cloneNode() 配合使用。另外,appendChild() 不仅可以用来追加新的元素,也可以挪动文档中现有的元素。
let container = document.createElement('div');
let text = document.createTextNode('hello world');
container.appendChild(text);
document.body.appendChild(container);
<div id="hello"> hello</div>
<div id="world">world</div>
<script>
let hello = document.getElementById('hello');
let world = document.getElementById('world');
world.appendChild(hello)
// 这时我们会发现hello 跑到 world 后边去了
</script>
insertBefore(newNode, oldNode)
在已有的子节点前插入一个新的子节点。使用该方法需要注意以下两点: 第二个参数是可选的,如果第二个参数不写,将默认添加到文档的最后,相当于appendChild(),此方法可返回新的子节点。
<div id="parent">
<div id="hello">hello</div>
<p id="world">world</p>
</div>
<script>
let parent = document.getElementById('parent');
let hello = document.getElementById('hello');
let world = document.getElementById('world');
parent.insertBefore(world, hello);
// 这时我们会发现world插入到了hello前面
</script>
3、替换节点
replaceChild(newNode, oldNode)
该是删除一个子节点并用一个新的节点代替原来节点的位置,使用时需要注意:
1、该方法接受两个参数,第一个参数是新节点,第二个参数是需要被替代的节点;
2、被替换的节点没有消失,只是在文档树中被移除了,没有了它的位置,但还存在与文档中;
3、这个方法需要在父节点上调用,如果替换成功则返回被替换的节点,如果失败则返回null。
<div id="app">
<div id="hello">hello</div>
</div>
<script>
let app = document.getElementById('app');
let hello = document.getElementById('hello');
let world = document.createElement('p');
app.replaceChild(world, hello);
// 这时候你打开控制台Elements查看,会发现app下边的节点变成了p
</script>
4、克隆/复制节点
cloneNode(boolean)
此方法接受一个布尔值参数,用于复制节点操作,使用时需注意:
1、参数boolean为false时,表示执行浅复制,即只复制节点本身;
2、参数boolean为true时,表示执行深复制,即会复制节点本身及其整个子节点树;
3、复制后返回的节点没有指定的父节点,不会被自动插入到文档中,在文档中处于游离状态;
4、如果克隆后,id一样,不要忘记setAttribute('id', 'another_id'),去改变新的节点id。
let hello = document.createTextNode('hello');
let container = document.createElement('p');
container.appendChild(hello);
document.body.appendChild(container);
let cloneP = container.cloneNode(true); // true 和 false 区别
document.body.appendChild(cloneP)
5、删除节点
removeChild(node)
该方法可以从子节点列表中删除某个节点。若删除成功,则此方法返回被删除的节点,若删除失败则返回null。如果你想把某个节点从一个地方移动到另一个地方,不必使用removeChild(),可以使用前面的appendChild() 和 insertBefore(),他们都会自动先删除节点,然后移动到你指定的地方。
<div id="app">
<p id="hello">hello</p>
<p id="world">world</p>
</div>
<script>
let app = document.getElementById('app');
let world = document.getElementById('world');
app.removeChild(world); // 这个方法也是由父元素来调用
</script>
如果不知道要删除的节点的父节点是什么,可以使用parentNode 属性。
<div id="app">
<p id="hello">hello</p>
<p id="world">world</p>
</div>
<script>
let world = document.getElementById('world');
let parent = world.parentNode;
parent.removeChild(world);
</script>
6、判断节点
hasChildNodes()
此方法可判断指定节点是否存在子节点,若存在一个或多个子节点,则返回值为true,否则返回值为false。
<div id="app">
<p id="hello">hello</p>
<p id="world">world</p>
</div>
<script>
let app = document.getElementById('app');
if (app.hasChildNodes) {
alert(app.childNodes.length);
}
</script>
节点属性操作
1、获取属性、设置属性、删除属性
getAttribute()
该方法用于获取节点的属性,获取的时候,如果属性不存在,则返回空,注意IE和Firefox返回不同,返回虽然不同,但是可以用一个方法来判断:if(app.getAttribute('title'))
<div id="app"></div>
<script>
let app = document.getElementById('app');
let getAttr = app.getAttribute('title');
console.log(getAttr);
</script>
setAttribute()
该方法用于设置节点属性
let p = document.createElement('p');
p.setAttribute('title', 'my demo');
removeAttribute()
该方法用于移除节点的属性
<div id="app"></div>
<script>
let app = document.getElementById('app');
let getAttr = app.getAttribute('title');
console.log(getAttr);
let removeAttr = getAttr.removeAttribute('title');
console.log(removeAttr);
</script>
判断属性
hasAttribute()
该方法用于判断一个元素是否具有指定的属性,如果当前元素节点拥有指定属性,则返回true,否则返回false,但是不返回那个属性的值。若文档中明确设置了指定的属性,或者是文档类型声明为该属性设置了默认值,则hasAttribute() 方法都返回true。
Comments | NOTHING