操作DOM

DOM(文档对象模型)

当网页被加载时,浏览器会创建页面的文档对象模型(Document Object Model)。

HTML DOM 模型被结构化为对象树:

通过这个对象模型,JavaScript 获得创建动态 HTML 的所有力量:

  • JavaScript 能改变页面中的所有 HTML 元素
  • JavaScript 能改变页面中的所有 HTML 属性
  • JavaScript 能改变页面中的所有 CSS 样式
  • JavaScript 能删除已有的 HTML 元素和属性
  • JavaScript 能添加新的 HTML 元素和属性
  • JavaScript 能对页面中所有已有的 HTML 事件作出反应
  • JavaScript 能在页面中创建新的 HTML 事件

什么是 DOM?

DOM 是一项 W3C (World Wide Web Consortium) 标准。

DOM 定义了访问文档的标准:

“W3C 文档对象模型(DOM)是中立于平台和语言的接口,它允许程序和脚本动态地访问、更新文档的内容、结构和样式。”

W3C DOM 标准被分为 3 个不同的部分:

  • Core DOM - 所有文档类型的标准模型
  • XML DOM - XML 文档的标准模型
  • HTML DOM - HTML 文档的标准模型

什么是 HTML DOM?

HTML DOM 是 HTML 的标准对象模型和编程接口。它定义了:

  • 作为对象的 HTML 元素
  • 所有 HTML 元素的属
  • 访问所有 HTML 元素的方法
  • 所有 HTML 元素的事件

换言之:HTML DOM 是关于如何获取、更改、添加或删除 HTML 元素的标准

选择器

在操作一个DOM节点前,我们需要通过各种方式先拿到这个DOM节点。最常用的方法是document.getElementById() document.getElementsByTagName() ,以及CSS选择器document.getElementsByClassName()

由于ID在HTML文档中是唯一的,所以document.getElementById()可以直接定位唯一的一个DOM节点。 document.getElementsByTagName() document.getElementsByClassName()总是返回一组DOM节点。要精确地选择DOM,可以先定位父节点,再从父节点开始选择,以缩小范围。

// 返回ID为'test'的节点:
var test = document.getElementById('test'); // 先定位ID为'test-table'的节点,再返回其内部所有tr节点:
var trs = document.getElementById('test-table').getElementsByTagName('tr'); // 先定位ID为'test-div'的节点,再返回其内部所有class包含red的节点:
var reds = document.getElementById('test-div').getElementsByClassName('red'); // 获取节点test下的所有直属子节点:
var cs = test.children; // 获取节点test下第一个、最后一个子节点:
var first = test.firstElementChild;
var last = test.lastElementChild;

第二种方法是使用querySelector()querySelectorAll() ,需要了解selector语法,然后使用条件来获取节点,更加方便:

// 通过querySelector获取ID为q1的节点:
var q1 = document.querySelector('#q1'); // 通过querySelectorAll获取q1节点内的符合条件的所有节点:
var ps = q1.querySelectorAll('div.highlighted > p');

更新DOM

拿到一个DOM节点后,我们可以对它进行更新。

可以直接修改节点的文本,方法有两种:

一种是修改 innerHTML 属性,这个方式非常强大,不但可以修改一个DOM节点的文本内容,还可以直接通过HTML片段修改DOM节点内部的子树:

// 获取<p id="p-id">...</p>
var p = document.getElementById('p-id');
// 设置文本为abc:
p.innerHTML = 'ABC'; // <p id="p-id">ABC</p>
// 设置HTML:
p.innerHTML = 'ABC <span style="color:red">RED</span> XYZ';
// <p>...</p>的内部结构已修改

用 innerHTML 时要注意,是否需要写入HTML。如果写入的字符串是通过网络拿到了,要注意对字符编码来避免XSS攻击。

第二种是修改 innerText 属性,这样可以自动对字符串进行HTML编码,保证无法设置任何HTML标签:

// 获取<p id="p-id">...</p>
var p = document.getElementById('p-id');
// 设置文本:
p.innerText = '<script>alert("Hi")</script>';
// HTML被自动编码,无法设置一个<script>节点:
// <p id="p-id">&lt;script&gt;alert("Hi")&lt;/script&gt;</p>

修改CSS也是经常需要的操作。DOM节点的 style 属性对应所有的CSS,可以直接获取或设置。因为CSS允许 font-size 这样的名称,但它并非JavaScript有效的属性名,所以需要在JavaScript中改写为驼峰式命名 fontSize

// 获取<p id="p-id">...</p>
var p = document.getElementById('p-id');
// 设置CSS:
p.style.color = '#ff0000';
p.style.fontSize = '20px';
p.style.paddingTop = '2em';

插入DOM

appendChild

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

如果这个DOM节点是空的,例如,,那么,直接使用 innerHTML = 'child'就可以修改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>

把 JavaScript 添加到的最后一项:

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 节点已经存在于当前的文档树,因此这个节点首先会从原先的位置删除,再插入到新的位置。

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>

删除DOM

要删除一个节点,首先要获得该节点本身以及它的父节点,然后,调用父节点的 removeChild 把自己删掉:

// 拿到待删除节点:
var self = document.getElementById('to-be-removed');
// 拿到父节点:
var parent = self.parentElement;
// 删除:
var removed = parent.removeChild(self);
removed === self; // true

注意到删除后的节点虽然不在文档树中了,但其实它还在内存中,可以随时再次被添加到别的位置。

当你遍历一个父节点的子节点并进行删除操作时,要注意, children 属性是一个只读属性,并且它在子节点变化时会实时更新。


JavaScript学习05(操作DOM)的更多相关文章

  1. JavaScript学习05 定时器

    JavaScript学习05 定时器 定时器1 用以指定在一段特定的时间后执行某段程序. setTimeout(): 格式:[定时器对象名=] setTimeout(“<表达式>”,毫秒) ...

  2. Javascript学习笔记——操作浏览器对象

    Javascript学习笔记 目前尝试利用javascript去对于一个浏览器对象完成一系列的访问及修改, 浏览器是网页显示.运行的平台,常用的浏览器有IE.火狐(Firefox).谷歌(Chrome ...

  3. JavaScript学习 - 基础(六) - DOM基础操作

    DOM: DOM定义了访问HTML 和XML 文档的标准:1.核心DOM 针对结构化文档的标准模型2.XMK DOM 针对XML文档的标准模型3.HTML DOM 针对HTML文档的标准模型 DOM节 ...

  4. JavaScript学习笔记(10)——JavaScript语法之操作DOM

    1.页面输出用document.write()方法,但是不可以在window.onload中用,否则整个html页面将被覆盖. 2.通过javascript获取对象后,改变对象中的html内容:doc ...

  5. JavaScript学习 - 基础(八) - DOM 节点 添加/删除/修改/属性值操作

    html代码: <!--添加/删除/修改 --> <div id="a1"> <button id="a2" onclick=&q ...

  6. javascript学习 真正理解DOM脚本编程技术背后的思路和原则

    本文学习来源于<javascriptDOM编程艺术>仅作笔记 学会怎样才能利用DOM脚本编程技术以一种既方便自己更体贴用户的方式去充实和完善你们的网页. 循序渐进:从最核心的内容开始,逐步 ...

  7. javascript学习笔记之DOM与表单

    DOM(文档对象模型),猫叔了一个层次化的节点树 一.DOM NODE相关公共属性与方法 DOM中所有节点都实现了NODE接口,该接口的公共属性和方法如下: 1.节点基本属性 1)NodeType 节 ...

  8. JavaScript学习笔记之DOM介绍

    目录 1.简介 2.方法 3.属性 4.访问节点 5.修改节点 6.添加节点 7.删除节点 8.替换节点 9.改变 CSS 1.简介 文档对象模型(Document Object Model,DOM) ...

  9. javascript学习笔记之DOM

    DOM(文档对象模型),描述了一个层次化的节点树 一.DOM NODE相关公共属性与方法 DOM中所有节点都实现了NODE接口,该接口的公共属性和方法如下: 1.节点基本属性 1)NodeType 节 ...

随机推荐

  1. Tomcat 中文乱码,设置UTF-8

    1.修改tomcat的conf目录下 server.xml文件加上 URIEncoding="UTF-8" <Connector port="8080" ...

  2. CRM系统如何帮助企业管理多条业务线的?

    在如今的市场环境中,许多企业为了提高销售效率,增加业绩收入,都会选择使用CRM客户关系管理系统来帮助进行对客户和销售的管理.CRM系统能够帮助企业在不同的产品线上同时开展营销活动.各个销售团队能够独立 ...

  3. (转发)forward与(重定向)redirect的区别

    (转发)forward与(重定向)redirect的区别 forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器.浏览器根本不知道服 ...

  4. HMM实现中文分词

    链接:https://pan.baidu.com/s/1uBjLC61xm4tQ9raDa_M1wQ  提取码:f7l1 推荐:https://blog.csdn.net/longgb123/arti ...

  5. spring cloud 微服务介绍(转)

    一.理解微服务   我们通过软件架构演进过程来理解什么是微服务,软件架构的发展经历了从单体结构.垂直架构.SOA架构到微服务架构的过程. 1. 单体架构 1.1 特点(1)所有的功能集成在一个项目工程 ...

  6. POJ 博弈论

    poj1704 Georgia and Bob 题目链接:http://poj.org/problem?id=1704 题意:如图所示,两个人在玩一个游戏,排成直线的格子上有n个棋子,两人依次将棋子向 ...

  7. facade层,service 层,domain层,dao 层设计

    转自http://fei-6666.iteye.com/blog/446247,记录下来 一,Service->DAO,只能在Service中注入DAO. 二,DAO只能操作但表数据,跨表操作放 ...

  8. ES6 let const关键字

    在es6中,引入了let和const关键字: 1.letES6 新增了let命令,用来声明变量.它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效. (1)在块级作用域里有效(比 ...

  9. React refs 的理解

    一.是什么 Refs 在计算机中称为弹性文件系统(英语:Resilient File System,简称ReFS) React 中的 Refs提供了一种方式,允许我们访问 DOM节点或在 render ...

  10. 如何掌握C#的核心技术

    如何掌握C#的核心技术 感谢网友毛大神制作的图. 引子 前不久看到一个段子,某年宁波交警引进人脸识别技术抓拍行人闯红灯,结果一天下来被发现闯红灯次数最多的是珠海女子董小姐,日闯红灯3000多次.宁波交 ...