[JavaScript] (Day-17) - DOM 基本操

作者: 已重置2020 | 来源:发表于2017-07-08 15:01 被阅读88次
Happiness takes no account of time. 幸福不觉光阴过。

由于 HTML 文档被浏览器解析后就是一棵 DOM 树,要改变 HTML 的结构,就需要通过 JavaScript 来操作 DOM。

操作一个 DOM 节点实际上就是这么几个操作:

  • 更新:更新该 DOM 节点的内容,相当于更新了该 DOM 节点表示的HTML 的内容;
  • 遍历:遍历该 DOM 节点下的子节点,以便进行进一步操作;
  • 添加:在该 DOM 节点下新增一个子节点,相当于动态增加了一个 HTML 节点;
  • 删除:将该节点从 HTML 中删除,相当于删掉了该 DOM 节点的内容以及它包含的所有子节点。

获取节点元素

在操作一个 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>的内部结构已修改

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

innerTexttextContent的区别在于读取属性时,innerText不返回隐藏元素的文本,而textContent返回所有文本

// 获取<p id="p_id">...</p>
var p = document.getElementById('p_id');

// 设置文本:
p.innerText = '<script>alert("Hi")</script>';

// HTML被自动编码,无法设置一个<script>节点:
// <p id="p-id"><script>alert("Hi")</script></p>

插入 DOM

获得某个 DOM 节点,然后在这个 DOM 节点内插入新的 DOM

方式一:使用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>

idjs 的标签插入到 <div>...</div> 便签最后一项

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

结果:

<!-- 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>

上面是把已知的元素插入到指定位置,但更多的时候我们会从零创建一个新的节点,然后插入到指定位置:

var list = document.getElementById('list');
var swift = document.createElement('p');
swift.id = 'swift';
swift.innerText = 'Swift';
list.appendChild(swift);

结果:

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


方式二: 使用 insertBefore 把子节点插入到指定的位置

使用parentElement.insertBefore(newElement, referenceElement);,子节点会插入到referenceElement之前。

还是以上面的 HTML 为例,假定我们要把Swift插入到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');
var ref = document.getElementById('python');
var swift = document.createElement('p');
swift.id = 'swift';
swift.innerText = 'Swift';
list.insertBefore(swift, ref);
<!-- HTML结构 -->
<div id="list">
    <p id="java">Java</p>
    <p id="swift">Swift</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

注意,当从子节点数组中删除节点时,需要防止数组越界

<div id="parent">
    <p>First</p>
    <p>Second</p>
</div>

执行删除操作

var parent = document.getElementById('parent');

parent.removeChild(parent.children[0]);

parent.removeChild(parent.children[1]); // <-- 浏览器报错

报错原因:

<p>First</p>节点被删除后,parent.children的节点数量已经从2变为了1,索引[1]已经不存在了。

相关文章

  • [JavaScript] (Day-17) - DOM 基本操

    由于 HTML 文档被浏览器解析后就是一棵 DOM 树,要改变 HTML 的结构,就需要通过 JavaScript...

  • DOM (javascript DOM节点操作)

    DOM (javascript DOM节点操作) 本节目录 查找DOM元素 DOM节点操作 javascript操...

  • 1.JavaScript 基础回顾

    JavaScript 基本组成 JavaScript由几部分构成? BOM、DOM、ECMAScript 数据类型...

  • 虚拟DOM理解

    1.Virtual DOM是一个基本的JavaScript对象,也是整个Virtual DOM树的基本。 2.Ja...

  • DOM增删改查基本操作

    DOM增删改查基本操作 基本概念 DOM是JavaScript操作网页的接口,全称为“文档对象模型”(Docume...

  • DOM 模型概述

    基本概念 DOM DOM 是 JavaScript 操作网页的接口,全称为“文档对象模型”(Document Ob...

  • JavaScript基础回顾

    JavaScript包含三大部分:DOM: Document Object Model 文档对象模型 一套完整的操...

  • JavaScript 复习DOM与常用API

    1.DOM的基本概念: DOM 是 JavaScript 操作网页的接口,全称为“文档对象模型”(Document...

  • JavaScript入门学习书籍到阶段书籍

    入门:《深入浅出JavaScript》《JavaScript DOM编程艺术》 《JavaScript DOM高级...

  • JavaScript入门篇

    快速认识JavaScript熟悉JavaScript基本语法窗口交互方法通过DOM进行网页元素的操作学会如何编写J...

网友评论

    本文标题:[JavaScript] (Day-17) - DOM 基本操

    本文链接:https://www.haomeiwen.com/subject/fytjhxtx.html