JavaScript插入DOM的操作讲解
当我们获得了某个dom节点,想在这个dom节点内插入新的dom,应该如何做?
如果这个dom节点是空的,例如,<p></p>,那么,直接使用innerhtml = '<span>child</span>'就可以修改dom节点的内容,相当于“插入”了新的dom节点。
如果这个dom节点不是空的,那就不能这么做,因为innerhtml会直接替换掉原来的所有子节点。
有两个办法可以插入新的节点。一个是使用appendchild,把一个子节点添加到父节点的最后一个子节点。例如:
<!-- html结构 -->
<p id="js">javascript</p>
<p id="list">
<p id="java">java</p>
<p id="python">python</p>
<p id="scheme">scheme</p>
</p>
把<p id="js">javascript</p>添加到<p id="list">的最后一项:
var
js = document.getelementbyid('js'),
list = document.getelementbyid('list');
list.appendchild(js);
现在,html结构变成了这样:
<!-- html结构 -->
<p id="list">
<p id="java">java</p>
<p id="python">python</p>
<p id="scheme">scheme</p>
<p id="js">javascript</p>
</p>
因为我们插入的js节点已经存在于当前的文档树,因此这个节点首先会从原先的位置删除,再插入到新的位置。
更多的时候我们会从零创建一个新的节点,然后插入到指定位置:
var
list = document.getelementbyid('list'),
haskell = document.createelement('p');
haskell.id = 'haskell';
haskell.innertext = 'haskell';
list.appendchild(haskell);
这样我们就动态添加了一个新的节点:
<!-- html结构 -->
<p id="list">
<p id="java">java</p>
<p id="python">python</p>
<p id="scheme">scheme</p>
<p id="haskell">haskell</p>
</p>
动态创建一个节点然后添加到dom树中,可以实现很多功能。举个例子,下面的代码动态创建了一个<style>节点,然后把它添加到<head>节点的末尾,这样就动态地给文档添加了新的css定义:
var d = document.createelement('style');
d.setattribute('type', 'text/css');
d.innerhtml = 'p { color: red }';
document.getelementsbytagname('head')[0].appendchild(d);
可以在chrome的控制台执行上述代码,观察页面样式的变化。
insertbefore
如果我们要把子节点插入到指定的位置怎么办?可以使用parentelement.insertbefore(newelement, referenceelement);,子节点会插入到referenceelement之前。
还是以上面的html为例,假定我们要把haskell插入到python之前:
<!-- html结构 -->
<p id="list">
<p id="java">java</p>
<p id="python">python</p>
<p id="scheme">scheme</p>
</p>
可以这么写:
var
list = document.getelementbyid('list'),
ref = document.getelementbyid('python'),
haskell = document.createelement('p');
haskell.id = 'haskell';
haskell.innertext = 'haskell';
list.insertbefore(haskell, ref);
新的html结构如下:
<!-- html结构 -->
<p id="list">
<p id="java">java</p>
<p id="haskell">haskell</p>
<p id="python">python</p>
<p id="scheme">scheme</p>
</p>
可见,使用insertbefore重点是要拿到一个“参考子节点”的引用。很多时候,需要循环一个父节点的所有子节点,可以通过迭代children属性实现:
var
i, c,
list = document.getelementbyid('list');
for (i = 0; i < list.children.length; i++) {
c = list.children[i]; // 拿到第i个子节点
}
练习
对于一个已有的html结构:
scheme
javascript
python
ruby
haskell
<!-- html结构 -->
<ol id="test-list">
<li class="lang">scheme</li>
<li class="lang">javascript</li>
<li class="lang">python</li>
<li class="lang">ruby</li>
<li class="lang">haskell</li>
</ol>
按字符串顺序重新排序dom节点:
'use strict';
// 测试:
;(function () {
var
arr, i,
t = document.getelementbyid('test-list');
if (t && t.children && t.children.length === 5) {
arr = [];
for (i=0; i<t.children.length; i++) {
arr.push(t.children[i].innertext);
}
if (arr.tostring() === ['haskell', 'javascript', 'python', 'ruby', 'scheme'].tostring()) {
console.log('测试通过!');
}
else {
console.log('测试失败: ' + arr.tostring());
}
}
else {
console.log('测试失败!');
}
})();
run
下一篇: 我想得轻微的心脏病 之女人惹不起