当我们获得了某个DOM节点,想在这个DOM节点内插入新的DOM,应该如何做?

如果这个DOM节点是空的,例如,<div></div>,那么,直接使用innerHTML = '<span>child</span>'就可以修改DOM节点的内容,相当于“插入”了新的DOM节点。

如果这个DOM节点不是空的,那就不能这么做,因为innerHTML会直接替换掉原来的所有子节点。

有两个办法可以插入新的节点。一个是使用appendChild,把一个子节点添加到父节点的最后一个子节点。例如:

<!-- HTML结构 -->
<p id="js">JavaScript</p>
<div id="list">
<p id="java">Java</p>
<p id="python">Python</p>
<p id="scheme">Scheme</p>
</div>

<p id="js">JavaScript</p>添加到<div id="list">的最后一项:

var
js = document.getElementById('js'),
list = document.getElementById('list');
list.appendChild(js);

现在,HTML结构变成了这样:

<!-- HTML结构 -->
<div id="list">
<p id="java">Java</p>
<p id="python">Python</p>
<p id="scheme">Scheme</p>
<p id="js">JavaScript</p>
</div>

因为我们插入的js节点已经存在于当前的文档树,因此这个节点首先会从原先的位置删除,再插入到新的位置。

更多的时候我们会从零创建一个新的节点,然后插入到指定位置:

var
list = document.getElementById('list'),
haskell = document.createElement('p');
haskell.id = 'haskell';
haskell.innerText = 'Haskell';
list.appendChild(haskell);

这样我们就动态添加了一个新的节点:

<!-- HTML结构 -->
<div id="list">
<p id="java">Java</p>
<p id="python">Python</p>
<p id="scheme">Scheme</p>
<p id="haskell">Haskell</p>
</div>

动态创建一个节点然后添加到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结构 -->
<div id="list">
<p id="java">Java</p>
<p id="python">Python</p>
<p id="scheme">Scheme</p>
</div>

可以这么写:

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结构 -->
<div id="list">
<p id="java">Java</p>
<p id="haskell">Haskell</p>
<p id="python">Python</p>
<p id="scheme">Scheme</p>
</div>

可见,使用insertBefore重点是要拿到一个“参考子节点”的引用。很多时候,需要循环一个父节点的所有子节点,可以通过迭代children属性实现:

var
i, c,
list = document.getElementById('list');
for (i = 0; i < list.children.length; i++) {
c = list.children[i]; // 拿到第i个子节点
}

练习

对于一个已有的HTML结构:

  1. Scheme
  2. JavaScript
  3. Python
  4. Ruby
  5. 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节点:

var tmp = [], ol = document.getElementById('test-list');
for (var i of ol.children) {tmp.push(i);}
tmp.sort((x, y) => {return x.innerText > y.innerText;});
for (var j of tmp) {ol.appendChild(j)};

廖雪峰js教程笔记13 插入DOM的更多相关文章

  1. 廖雪峰js教程笔记12 用DOM更新 innerHMTL 和修改css样式

    拿到一个DOM节点后,我们可以对它进行更新. 可以直接修改节点的文本,方法有两种: 一种是修改innerHTML属性,这个方式非常强大,不但可以修改一个DOM节点的文本内容,还可以直接通过HTML片段 ...

  2. 廖雪峰js教程笔记11 操作DOM(包含作业)

    由于HTML文档被浏览器解析后就是一棵DOM树,要改变HTML的结构,就需要通过JavaScript来操作DOM. 始终记住DOM是一个树形结构.操作一个DOM节点实际上就是这么几个操作: 更新:更新 ...

  3. 廖雪峰js教程笔记10 浏览器对象

    JavaScript可以获取浏览器提供的很多对象,并进行操作. window window对象不但充当全局作用域,而且表示浏览器窗口. window对象有innerWidth和innerHeight属 ...

  4. 廖雪峰js教程笔记6 generator一个坑 看完python在回来填坑

    generator(生成器)是ES6标准引入的新的数据类型.一个generator看上去像一个函数,但可以返回多次. ES6定义generator标准的哥们借鉴了Python的generator的概念 ...

  5. 廖雪峰js教程笔记14 file文件操作

    在HTML表单中,可以上传文件的唯一控件就是<input type="file">. 注意:当一个表单包含<input type="file" ...

  6. 廖雪峰js教程笔记9 json

    JSON是JavaScript Object Notation的缩写,它是一种数据交换格式. 在JSON出现之前,大家一直用XML来传递数据.因为XML是一种纯文本格式,所以它适合在网络上交换数据.X ...

  7. 廖雪峰js教程笔记8 date对象介绍和处理

    在JavaScript中,Date对象用来表示日期和时间. 要获取系统当前时间,用: var now = new Date(); now; // Wed Jun 24 2015 19:49:22 GM ...

  8. 廖雪峰js教程笔记7 基本类型和包装类型

    在JavaScript的世界里,一切都是对象. 但是某些对象还是和其他对象不太一样.为了区分对象的类型,我们用typeof操作符获取对象的类型,它总是返回一个字符串: typeof 123; // ' ...

  9. 廖雪峰js教程笔记5 Arrow Function(箭头函数)

    为什么叫Arrow Function?因为它的定义用的就是一个箭头: x => x * x 上面的箭头函数相当于: function (x) { return x * x; } 箭头函数 阅读: ...

随机推荐

  1. Objective-C总Runtime的那点事儿(一)消息机制

    最近在找工作,Objective-C中的Runtime是经常被问到的一个问题,几乎是面试大公司必问的一个问题.当然还有一些其他问题也几乎必问,例 如:RunLoop,Block,内存管理等.其他的问题 ...

  2. request 获取服务根目录地址

    这是常用的request获取服务地址的常用方式. 源请求服务地址:http://localhost/api-server/1/forum/thread/hot_topic?sex=1 String p ...

  3. CSS实现正方体旋转

    代码如下: <!DOCTYPE html><html lang="en"><head>    <meta charset="UT ...

  4. flask-whooshalchemy需要注意的一点

    在学习mega—tutorial时全文搜索模块遇到了问题,那就是使用全文搜索查询出来的数据为空的列表,输出了sql语句后发现where后没有条件,困扰了许久,后来才发现是自己不细心,在进行全文索引时应 ...

  5. Trie tree实践

    1.Trie树 Trie树即字典树或前缀树, 2.实践 代码实践如下: package cn.edu.buaa.trie; import java.util.HashSet; /** * @autho ...

  6. Zookeeper的安装和使用

    首先在Zookeeper官网下载最新版本,下载后解压到用户目录下. tar -zxvf zookeeper-3.4.8.tar.gz 重命名conf目录下zoo_sample.cfg文件为zoo.cf ...

  7. fatal: could not read Username for 'https://github.com': No such file or directo

    Git push origin master报错 fatal: could not read Username for 'https://github.com': No such file or di ...

  8. HTML5在canvas中绘制复杂形状附效果截图

    HTML5在canvas中绘制复杂形状附效果截图 一.绘制复杂形状或路径 在简单的矩形不能满足需求的情况下,绘图环境提供了如下方法来绘制复杂的形状或路径. beginPath() : 开始绘制一个新路 ...

  9. 如何在网页中添加“QQ交流”

    今天在撸码时,想到这个问题,有些网页中会有诸如,那么如何在网页添加"QQ交谈"? 第一步.登录QQ: 第二步.打开网页:QQ推广,启用QQ通讯组件: 第三步.选择组件样式,设置提示 ...

  10. 大熊君JavaScript插件化开发------(实战篇之DXJ UI ------ ItemSelector重构完结版)

    一,开篇分析 Hi,大家好!大熊君又和大家见面了,还记得上一篇文章吗.主要讲述了以“jQuery的方式如何开发插件”,以及过程化设计与面向对象思想设计相结合的方式是 如何设计一个插件的,两种方式各有利 ...