目录
一、节点创建型API
在这里,我将常用的DOM操作api进行分类,首先要介绍的是创建型的api。这一类型的api,简而言之就是用来创建节点的
1.1 createElement
createElement通过传入指定的一个标签名来创建一个元素,如果传入的标签名是一个未知的,则会创建一个自定义的标签,注意:IE8以下浏览器不支持自定义标签
var div = document.createElement("div");
使用createElement要注意:通过createElement创建的元素并不属于html文档,它只是创建出来,并未添加到html文档中,要调用appendChild或insertBefore等方法将其添加到HTML文档树中;
1.2 createTextNode
createTextNode用来创建一个文本节点,用法如下
var textNode = document.createTextNode("一个TextNode");
createTextNode接收一个参数,这个参数就是文本节点中的文本,和createElement一样,创建后的文本节点也只是独立的一个节点,同样需要append Child将其添加到HTML文档树中
1.3 cloneNode
cloneNode是用来返回调用方法的节点的一个副本,它接收一个bool参数,用来表示是否复制子元素,使用如下:
var parent = document.getElementById("parentElement");
var parent2 = parent.cloneNode(true);// 传入true
parent2.id = "parent2";
这段代码通过cloneNode复制了一份parent元素,其中cloneNode的参数为true,表示parent的子节点也被复制,如果传入false,则表示只复制了parent节点
这里有几点要注意:
和createElement一样,cloneNode创建的节点只是游离有html文档外的节点,要调用appendChild方法才能添加到文档树中
如果复制的元素有id,则其副本同样会包含该id,由于id具有唯一性,所以在复制节点后必须要修改其id
调用接收的bool参数最好传入,如果不传入该参数,不同浏览器对其默认值的处理可能不同
除此之外,我们还有一个需要注意的点:
如果被复制的节点绑定了事件,则副本也会跟着绑定该事件吗?这里要分情况讨论:
如果是通过addEventListener或者比如onclick进行绑定事件,则副本节点不会绑定该事件
如果是内联方式绑定比如<div onclick="showParent()"></div>
这样的话,副本节点同样会触发事件
需要注意下面几点:
- 它们创建的节点只是一个孤立的节点,
- 要通过appendChild添加到文档中
- cloneNode要注意如果被复制的节点是否包含子节点以及事件绑定等问题
二、页面修改形API
createElement、createTextNode、cloneNode它们只是创建节点,并没有真正修改到页面内容,而是要调用appendChild来将其添加到文档树中。我在这里将这类会修改到页面内容归为一类。
修改页面内容的api主要包括:
- appendChild(追加为子元素)
- insertBefore(插入前面)
- removeChild(删除子元素)
- replaceChild(替换子元素)
2.1 appendChild
appendChild,就是将指定的节点添加到调用该方法的节点的子元素的末尾。调用方法如下:
parent.appendChild(child);
child节点将会作为parent节点的最后一个子节点
注意:
- 如果被添加的节点是一个页面中存在的节点,则执行后这个节点将会添加到指定位置,其原本所在的位置将移除该节点,也就是说不会同时存在两个该节点在页面上,相当于把这个节点移动到另一个地方
- 如果child绑定了事件,被移动时,它依然绑定着该事件
2.2 insertBefore
insertBefore用来添加一个节点到一个参照节点之前
parentNode.insertBefore(newNode,refNode);
- parentNode表示新节点被添加后的父节点
- newNode表示要添加的节点
- refNode表示参照节点,新节点会添加到这个节点之前
<div id="parent">
父节点
<div id="child">子元素</div>
</div>
<input type="button" id="insertNode" value="插入节点" />
<script>
var parent = document.getElementById("parent");
var child = document.getElementById("child");
document.getElementById("insertNode").onclick = function(){
var newNode = document.createElement("div");
newNode.textContent = "新节点"
parent.insertBefore(newNode,child);
}
</script>
和appendChild一样,如果插入的节点是页面上的节点,则会移动该节点到指定位置,并且保留其绑定的事件。
关于第二个参数参照节点还有几个注意的地方:
refNode
是必传的,如果不传该参数会报错- 如果refNode是undefined或null,则insertBefore会将节点添加到子元素的末尾
2.3 removeChild
let oldChild = node.removeChild(child);
//或者
element.removeChild(child);
- child 是要移除的那个子节点.
- node 是child的父节点.
- oldChild保存对删除的子节点的引用. oldChild === child.
被移除的这个子节点仍然存在于内存中,只是没有添加到当前文档的DOM树中,因此,你还可以把这个节点重新添加回文档中,当然,实现要用另外一个变量比如上例中的oldChild来保存这个节点的引用. 如果使用上述语法中的第二种方法, 即没有使用 oldChild 来保存对这个节点的引用, 则认为被移除的节点已经是无用的,在短时间内将会被内存管理回收.
如果上例中的child节点不是node节点的子节点,则该方法会抛出异常.
// 先定位父节点,然后删除其子节点
var d = document.getElementById("top");
var d_nested = document.getElementById("nested");
var throwawayNode = d.removeChild(d_nested);
// 无须定位父节点,通过parentNode属性直接删除自身
var node = document.getElementById("nested");
if (node.parentNode) {
node.parentNode.removeChild(node);
}
// 移除一个元素节点的所有子节点
var element = document.getElementById("top");
while (element.firstChild) {
element.removeChild(element.firstChild);
}
2.4 replaceChild
replaceChild用于使用一个节点替换另一个节点,用法如下
parent.replaceChild(newChild,oldChild);
newChild是替换的节点,可以是新的节点,也可以是页面上的节点,如果是页面上的节点,则其将被转移到新的位置
oldChild是被替换的节点
三、元素属性型操作
3.1 getAttribute()(获取属性)
getAttribute()用于获取元素的attribute值
node.getAttribute('id');
//表示获取node元素的id属性的 ‘值’
3.2 createAttribute()(创建属性)
createAttribute()
方法生成一个新的属性对象节点,并返回它。
attribute = document.createAttribute(name);
createAttribute方法的参数name,是属性的名称。
3.3 setAttribute()(设置属性)
setAttribute()方法用于设置元素属性
var node = document.getElementById("div1");
node.setAttribute(name, value);
//name为属性名称 ;value为属性值
例如
var node = document.getElementById("div1");
node.setAttribute("id", "ct");
等同于
var node = document.getElementById("div1");
var a = document.createAttribute("id");
a.value = "ct";
node.setAttributeNode(a);
3.4 romoveAttribute()(删除属性)
removeAttribute()用于删除元素属性
node.removeAttribute('id');
四、innerText和innerHTML
区别:
- innerText返回的是元素内包含的文本内容(只返回文本节点类型);
- innerHTML返会元素内HTML结构,包括元素节点、注释节点、文本节点;