1、DOM操作梗概

本篇内容实际上在另一篇笔记《从JS和jQuery浅谈DOM操作》已经提到了重点的地方,可以戳链接另外进行阅读。

以前提到过,实际上HTML在被浏览器加载以后,会变成 “一棵DOM树”,里面的节点都是HTML DOM对象,而我们针对于DOM的操作,也就是针对这些节点对象来进行的,一般来说就是增、删、改、查(遍历)操作。

最常见的获取DOM节点的方式,无非是 document.getElementById()、document.getElementsByTagName()、document.getElementsByClassName() 等诸如此类,在这里再说说另一种方式。

还有一种方式是使用 querySelector() 和 querySelectorAll(),需要了解selector语法,这个类似jQuery选择器,十分方便:
  1. // 通过querySelector获取ID为q1的节点
  2. var q1 = document.querySelector('#q1');
  3. // 通过querySelectorAll获取q1节点内的符合条件的所有节点
  4. var ps = q1.querySelectorAll('div.highlighted > p');
5
 
1
  1. // 通过querySelector获取ID为q1的节点
2
  1. var q1 = document.querySelector('#q1');
3
  1.  
4
  1. // 通过querySelectorAll获取q1节点内的符合条件的所有节点
5
  1. var ps = q1.querySelectorAll('div.highlighted > p');

但是这种方式,低版本的IE<8是不支持idea,而且IE8也仅仅是有限支持,所以在使用时要注意版本兼容性。

严格地讲,我们这里的DOM节点是指DOM对象,也就是Element,但是DOM节点实际上是Node,在HTML中,Node包括Element、Comment、CDATA_SECTION等很多种,以及根节点Document类型,但是,绝大多数时候我们只关心Element,也就是实际控制页面结构的Node,其他类型的Node忽略即可。根节点Document已经自动绑定为全局变量document。

2、更新DOM

第一种方式可以修改 innerHTML 属性,这个方式不光可以修改文本,同时可以修改HTML:
  1. // 获取<p id="p-id">...</p>
  2. var p = document.getElementById('p-id');
  3. // 设置文本为abc:
  4. p.innerHTML = 'ABC'; // <p id="p-id">ABC</p>
  5. // 设置HTML:
  6. p.innerHTML = 'ABC <span style="color:red">RED</span> XYZ';
  7. // <p>...</p>的内部结构已修改
7
 
1
  1. // 获取<p id="p-id">...</p>
2
  1. var p = document.getElementById('p-id');
3
  1. // 设置文本为abc:
4
  1. p.innerHTML = 'ABC'; // <p id="p-id">ABC</p>
5
  1. // 设置HTML:
6
  1. p.innerHTML = 'ABC <span style="color:red">RED</span> XYZ';
7
  1. // <p>...</p>的内部结构已修改

第二种方式就是修改 innerText 属性或 textContent 属性,两者区别在于前者不会返回隐藏元素的文本,而后者返回所有文本(IE<9不支持textContent),但是这种方式没办法设置HTML标签:
  1. // 获取<p id="p-id">...</p>
  2. var p = document.getElementById('p-id');
  3. // 设置文本:
  4. p.innerText = '<script>alert("Hi")</script>';
  5. // HTML被自动编码,无法设置一个<script>节点:
  6. // <p id="p-id">&lt;script&gt;alert("Hi")&lt;/script&gt;</p>
6
 
1
  1. // 获取<p id="p-id">...</p>
2
  1. var p = document.getElementById('p-id');
3
  1. // 设置文本:
4
  1. p.innerText = '<script>alert("Hi")</script>';
5
  1. // HTML被自动编码,无法设置一个<script>节点:
6
  1. // <p id="p-id">&lt;script&gt;alert("Hi")&lt;/script&gt;</p>

3、插入DOM

因为innerHTML会替换掉原来的内容,所以我们不能使用这种方式来进行DOM的插入操作。

3.1 插入父节点的最后一个子节点 appendChild

第一种方式我们可以使用 appendChild() 方法,这个方法可以将一个子节点添加到父节点的最后一个子节点:
  1. <!-- HTML结构 -->
  2. <p id="js">JavaScript</p>
  3. <div id="list">
  4. <p id="java">Java</p>
  5. <p id="python">Python</p>
  6. <p id="scheme">Scheme</p>
  7. </div>
  8. //js操作
  9. var js = document.getElementById('js'),
  10. var list = document.getElementById('list');
  11. list.appendChild(js);
  12. <!-- 新的HTML结构 -->
  13. <div id="list">
  14. <p id="java">Java</p>
  15. <p id="python">Python</p>
  16. <p id="scheme">Scheme</p>
  17. <p id="js">JavaScript</p>
  18. </div>
21
 
1
  1. <!-- HTML结构 -->
2
  1. <p id="js">JavaScript</p>
3
  1. <div id="list">
4
  1.    <p id="java">Java</p>
5
  1.    <p id="python">Python</p>
6
  1.    <p id="scheme">Scheme</p>
7
  1. </div>
8
  1.  
9
  1. //js操作
10
  1. var js = document.getElementById('js'),
11
  1. var list = document.getElementById('list');
12
  1. list.appendChild(js);
13
  1.  
14
  1. <!-- 新的HTML结构 -->
15
  1. <div id="list">
16
  1.    <p id="java">Java</p>
17
  1.    <p id="python">Python</p>
18
  1.    <p id="scheme">Scheme</p>
19
  1.    <p id="js">JavaScript</p>
20
  1. </div>
21
  1.  

或者从零创建和插入一个新的节点:
  1. var list = document.getElementById('list'),
  2. var haskell = document.createElement('p');
  3. haskell.id = 'haskell';
  4. haskell.innerText = 'Haskell';
  5. list.appendChild(haskell);
  6. <!-- HTML结构 -->
  7. <div id="list">
  8. <p id="java">Java</p>
  9. <p id="python">Python</p>
  10. <p id="scheme">Scheme</p>
  11. <p id="haskell">Haskell</p>
  12. </div>
13
 
1
  1. var list = document.getElementById('list'),
2
  1. var haskell = document.createElement('p');
3
  1. haskell.id = 'haskell';
4
  1. haskell.innerText = 'Haskell';
5
  1. list.appendChild(haskell);
6
  1.  
7
  1. <!-- HTML结构 -->
8
  1. <div id="list">
9
  1.    <p id="java">Java</p>
10
  1.    <p id="python">Python</p>
11
  1.    <p id="scheme">Scheme</p>
12
  1.    <p id="haskell">Haskell</p>
13
  1. </div>

3.2 插入指定位置 insertBefore

parentElement.insertBefore(newElement, referenceElement) 这个方法,子节点会插入到referenceElement之前。
  1. <!-- HTML结构 -->
  2. <div id="list">
  3. <p id="java">Java</p>
  4. <p id="python">Python</p>
  5. <p id="scheme">Scheme</p>
  6. </div>
  7. //js操作
  8. var list = document.getElementById('list'),
  9. var ref = document.getElementById('python'),
  10. var haskell = document.createElement('p');
  11. haskell.id = 'haskell';
  12. haskell.innerText = 'Haskell';
  13. list.insertBefore(haskell, ref);
  14. <!-- 新的HTML结构 -->
  15. <div id="list">
  16. <p id="java">Java</p>
  17. <p id="haskell">Haskell</p>
  18. <p id="python">Python</p>
  19. <p id="scheme">Scheme</p>
  20. </div>
x
 
1
  1. <!-- HTML结构 -->
2
  1. <div id="list">
3
  1.    <p id="java">Java</p>
4
  1.    <p id="python">Python</p>
5
  1.    <p id="scheme">Scheme</p>
6
  1. </div>
7
  1.  
8
  1. //js操作
9
  1. var list = document.getElementById('list'),
10
  1. var ref = document.getElementById('python'),
11
  1. var haskell = document.createElement('p');
12
  1. haskell.id = 'haskell';
13
  1. haskell.innerText = 'Haskell';
14
  1. list.insertBefore(haskell, ref);
15
  1.  
16
  1. <!-- 新的HTML结构 -->
17
  1. <div id="list">
18
  1.    <p id="java">Java</p>
19
  1.    <p id="haskell">Haskell</p>
20
  1.    <p id="python">Python</p>
21
  1.    <p id="scheme">Scheme</p>
22
  1. </div>

很多时候,我们还需要循环一个父节点的所有子节点,可以通过迭代 children 属性实现:
  1. var i, c,
  2. var list = document.getElementById('list');
  3. for (i = 0; i < list.children.length; i++) {
  4. c = list.children[i]; // 拿到第i个子节点
  5. }
5
 
1
  1. var i, c,
2
  1. var list = document.getElementById('list');
3
  1. for (i = 0; i < list.children.length; i++) {
4
  1.    c = list.children[i]; // 拿到第i个子节点
5
  1. }

4、删除DOM

要删除一个节点,首先要获得该节点本身以及它的父节点,调用父节点的 removeChild 把自己删除:
(要杀掉自己,要先认清自己并找来自己的老爹,让老爹杀死自己,囧jz)
  1. // 拿到待删除节点:
  2. var self = document.getElementById('to-be-removed');
  3. // 拿到父节点:
  4. var parent = self.parentElement;
  5. // 删除:
  6. var removed = parent.removeChild(self);
  7. removed === self; // true
 
1
  1. // 拿到待删除节点:
2
  1. var self = document.getElementById('to-be-removed');
3
  1. // 拿到父节点:
4
  1. var parent = self.parentElement;
5
  1. // 删除:
6
  1. var removed = parent.removeChild(self);
7
  1. removed === self; // true

如果需要循环遍历删除,一定要注意使用children属性的变化,索引的变化。


05浏览器-02-操作DOM的更多相关文章

  1. JavaScript学习05(操作DOM)

    操作DOM DOM(文档对象模型) 当网页被加载时,浏览器会创建页面的文档对象模型(Document Object Model). HTML DOM 模型被结构化为对象树: 通过这个对象模型,Java ...

  2. 详解Google Chrome浏览器(操作篇)(下)

    开篇概述 由于最近忙于公司产品的架构与研发,已经三个多月没有写博客了,收到有些朋友的来信,问为什么不及时更新博客内容呢,他们说他们正期待着某些内容.对此,非常抱歉,那么我在此也给各位朋友一些承诺,从即 ...

  3. 【ASP.NET MVC系列】浅谈Google Chrome浏览器(操作篇)(下)

    ASP.NET MVC系列文章 [01]浅谈Google Chrome浏览器(理论篇) [02]浅谈Google Chrome浏览器(操作篇)(上) [03]浅谈Google Chrome浏览器(操作 ...

  4. Javascript操作DOM常用API总结

    基本概念 在讲解操作DOM的api之前,首先我们来复习一下一些基本概念,这些概念是掌握api的关键,必须理解它们. Node类型 DOM1级定义了一个Node接口,该接口由DOM中所有节点类型实现.这 ...

  5. mui项目中如何使用原生JavaScript代替jquery来操作dom 转自【B5教程网】:http://www.bcty365.com/content-146-3661-1.html

    最近在用mui写页面,当然了在移动App里引入jq或zepto这些框架,肯定是极不理性的.原生JS挺简单,为何需要jq?jq的成功当时是因为ie6.7.8.9.10.chrome.ff这些浏览器不兼容 ...

  6. 三、jquery操作DOM

    DOM(Document Object Model, 文档对象模型)为文档提供了一种结构化的表示方法,通过该方法可以改变文档的内容和展示形式.在实际运用中,DOM更像是桥梁,通过它可以实现跨平台.跨语 ...

  7. jQuery操作Dom、jQuery事件机制、jQuery补充部分

    jQuery操作Dom: 修改属性: //使用attr()方法 //attr(name, value) //name:要修改的属性的属性名 //value:对应的值 //attr方法,如果当前标签有要 ...

  8. 浏览器兼容性小记-DOM篇(二)

    1.DOM中的所有节点都继承自Node类型,IE9之前将DOM节点作为COM对象来实现:每个DOM节点都有一个nodeType属性来表明节点类型,总共有12个类型: Node.ELEMENT_NODE ...

  9. 【面试必备】javascript操作DOM元素

    前言 时间过的真快,不知不觉就到年底了.问问自己,这一年你对自己的工作满意吗? 评价标准是什么呢?当然是马云的那两条准则了:钱给到了吗?干的爽吗?如果答案都是no,那么,你准备好跳槽了吗? 为了应对年 ...

随机推荐

  1. Ubuntu Docker 简单安装 GitLab

    相关博文: Ubuntu 简单安装 Docker Ubuntu 简单安装和配置 GitLab 服务器版本 Ubuntu 16.04 LTS. 1. 安装和配置 安装命令: sudo docker ru ...

  2. Struts2学习笔记(九)——数据校验

    Struts2的数据校验属于服务器端校验,Struts2 支持校验方式 : 手动校验(代码校验) :在服务器端通过编写java代码,完成数据校验 自动校验(配置校验) :XML配置校验(主流) 和 注 ...

  3. 带你走进SAP项目实施过程——前言(0)

    欢迎关注博主的微信公众号,每天提供原创的SAP技术和项目管理新资讯! 一直很想写一些关于SAP项目管理以及实施过程的系列文章,讲述企业SAP项目从立项开始到启动,再到实施过程,直到最后的上线及总结.我 ...

  4. TIKV副本一致性检查机制分析

    背景 TIKV使用raft协议来实现副本同步,任何时刻写入一个KEY-VAL键值对,都会基于RAFT协议复制到不同机器的三个副本上,raft协议本身能保证副本同步的强一致性,但是任何系统都可能存在BU ...

  5. 如何删除当前正在使用的SQLLite文件?

    从网上搜索一大堆,套路几乎相同,但自己就是不行,怎么也不行,为什么不行呢?不行的话别人肯定不来坑博友了呀.然后放了一会,去拿下午茶回来,再次来看,恍然大悟,What?这么简单. 一开始代码如下: he ...

  6. web本地存储

    Web本地存储 通过本地存储(Local Storage),web 应用程序能够在用户浏览器中对数据进行本地的存储. 在 HTML5 之前,应用程序数据只能存储在 cookie 中,包括每个服务器请求 ...

  7. mysql查看表结构2种方式对比

    1.desc t_bookType; 2.show create table t_bookType; 相信大部分人还是喜欢第一种查看表结构方式.

  8. C# 爬虫 抓取小说

    心血来潮,想研究下爬虫,爬点小说. 通过百度选择了个小说网站,随便找了一本小书http://www.23us.so/files/article/html/13/13655/index.html. 1. ...

  9. if处理多分支结构

    实例1 import java.util.Scanner; /** * Created by liwenj on 2017/7/17. */ public class test7 { public s ...

  10. python 小技巧 防止SSL报错信息

    代码里面 只需要添加如下2行: import ssl ssl._create_default_https_context = ssl._create_unverified_context