本文共 3812 字,大约阅读时间需要 12 分钟。
答案:
创建节点
createElement
createTextNode
createDocumentFragment(临时节点)
修改节点
appendChild parent.appendChild(child)
insertBefore parentNode.insertBefore(newNode,refNode);
removeChild parent.removeChild(node)
replaceChild
详细解析:
一、创建节点
createElement
createElement通过传入指定的一个标签名来创建一个元素,如果传入的标签名是一个未知的,则会创建一个自定义的标签。
var div = document.createElement("div");
注意:通过createElement创建的元素并不属于html文档,它只是创建出来,并未添加到html文档中,要调用appendChild或insertBefore等方法将其添加到HTML文档树中。
createTextNode
createTextNode用来创建一个文本节点。
var textNode = document.createTextNode("一个TextNode");
createTextNode接收一个参数,这个参数就是文本节点中的文本,和createElement一样,创建后的文本节点也只是独立的一个节点,同样需要appendChild将其添加到HTML文档树中。
createDocumentFragment(临时节点)
createDocumentFragment方法用来创建一个DocumentFragment,表示一种轻量级的文档,它的作用主要是存储临时的节点用来准备添加到文档中。createDocumentFragment方法主要是用于添加大量节点到文档中时会使用到。
假设要循环一组数据,然后创建多个节点添加到文档中,代码如下:
1
这段代码将按钮绑定了一个事件,这个事件创建了100个li节点,然后依次将其添加HTML文档中。这样做有一个缺点:每次一创建一个新的元素,然后添加到文档树中,这个过程会造成浏览器的回流。所谓回流简单说,就是指元素大小和位置会被重新计算,如果添加的元素太多,会造成性能问题。这个时候,就是使用createDocumentFragment了。
DocumentFragment不是文档树的一部分,它是保存在内存中的,所以不会造成回流问题。我们修改上面的代码如下:
1 document.getElementById("btnAdd").onclick = function(){ 2 var list = document.getElementById("list"); 3 var fragment = document.createDocumentFragment(); 4 5 for(var i = 0;i < 100; i++){ 6 var li = document.createElement("li"); 7 li.textContent = i; 8 fragment.appendChild(li); 9 }10 11 list.appendChild(fragment);12 }
优化后的代码主要是创建了一个fragment,每次生成的li节点先添加到fragment,最后一次性添加到list。
创建型API总结
创建型api主要包括createElement,createTextNode,createDocumentFragment 三个方法,需要注意下面几点:
(1)它们创建的节点只是一个孤立的节点,要通过appendChild添加到文档中 (2)使用createDocumentFragment来解决添加大量节点时的性能问题
二、修改节点
appendChild
appendChild我们在前面已经用到多次,就是将指定的节点添加到调用该方法的节点的子元素的末尾。调用方法如下:
parent.appendChild(child);
child节点将会作为parent节点的最后一个子节点。
注意:如果被添加的节点是一个页面中存在的节点,则执行后这个节点将会添加到指定位置,其原本所在的位置将移除该节点,也就是说不会同时存在两个该节点在页面上,相当于把这个节点移动到另一个地方。
12 要被添加的节点 34 5 6 78 要移动的位置 910
11 document.getElementById("btnMove").onclick = function(){12 var child = document.getElementById("child");13 document.getElementById("parent").appendChild(child);14 }
这段代码主要是获取页面上的child节点,然后添加到指定位置,可以看到原本的child节点被移动到parent中了。
注意:如果child绑定了事件,被移动时,它依然绑定着该事件。
insertBefore
insertBefore用来添加一个节点到一个参照节点之前,用法如下:
parentNode.insertBefore(newNode,refNode);
12 父节点 374 子元素 56
8 var parent = document.getElementById("parent"); 9 var child = document.getElementById("child");10 document.getElementById("insertNode").onclick = function(){11 var newNode = document.createElement("div");12 newNode.textContent = "新节点";13 parent.insertBefore(newNode,child);14 }
这段代码创建了一个新节点,然后添加到child节点之前。和appendChild一样,如果插入的节点是页面上的节点,则会移动该节点到指定位置,并且保留其绑定的事件。
关于第二个参数参照节点还有几个注意的地方:
(1)refNode是必传的,如果不传该参数会报错 (2)如果refNode是 undefined 或 null,则insertBefore会将节点添加到子元素的末尾removeChild
removeChild顾名思义,就是删除指定的子节点并返回,用法如下:
var deletedChild = parent.removeChild(node);
deletedChild指向被删除节点的引用,它等于node,被删除的节点仍然存在于内存中,可以对其进行下一步操作。
注意:如果被删除的节点不是其子节点,则程序将会报错。我们可以通过下面的方式来确保可以删除:
1 if(node.parentNode){2 node.parentNode.removeChild(node);3 }
通过节点自己获取节点的父节点,然后将自身删除。
replaceChild
replaceChild用于使用一个节点替换另一个节点,用法如下。
parent.replaceChild(newChild,oldChild);
newChild是替换的节点,可以是新的节点,也可以是页面上的节点,如果是页面上的节点,则其将被转移到新的位置
oldChild是被替换的节点。页面修改型API总结
页面修改型api主要是这四个接口,要注意几个特点:
(1)不管是新增还是替换节点,如果新增或替换的节点是原本存在页面上的,则其原来位置的节点将被移除,也就是说同一个节点不能存在于页面的多个位置 (2)节点本身绑定的事件不会消失,会一直保留着。转载地址:http://tjuvi.baihongyu.com/