欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

JavaScript插入DOM的操作讲解

程序员文章站 2022-05-12 13:01:49
当我们获得了某个dom节点,想在这个dom节点内插入新的dom,应该如何做? 如果这个dom节点是空的,例如,

,那么,直接使用innerhtml = '...

当我们获得了某个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