JavaScript之文档对象模型DOM

166 阅读5分钟

HTML DOM(文档对象模型)

前言

使用JavaScript去改变HTML的结构,就是用JS去操作DOM。因为HTML文档被浏览器解析之后就是一颗DOM树。故操作DOM就是去改变HTML的结构。

1、DOM解析:

(1)文档:表示的是整个HTML网页文档。一个网页就是一个文档。

(2)对象:对象表示将网页中的每个部分都转换成一个对象。

(3)模型:用模型来表示对象之间的关系,方便获取对象。父子关系,兄弟关系。

在这里插入图片描述

2、节点:Node – 构成HTML文档的最基本的单元。

在这里插入图片描述

3、文档节点document

文档节点document是浏览器提供的,即查找节点的入口。文档节点代表的是整个网页。通过文档节点获取各种子节点。

4、文档加载

浏览器在加载一个页面的时候,是至上而下的顺序加载的。所以script标签内要写在页面的下边。

一、获取DOM节点 – 得到HTML元素

// HTML
<p id="q1" class="red">id选择器</p>

<style>
    #q1{
    }
    
    .red{
    }
</style>

1、通过HTML里的标识

  • 通过 id 找到 HTML 元素 – getElementById
  • 通过标签名找到 HTML 元素 – getElementsByTagName
  • 通过类名找到 HTML 元素 – getElementsByClassName
// 返回ID为'test'的节点
var test = document.getElementById('test');

// 先定位ID为'test-table'的节点,再返回其内部所有p标签:
var p = document.getElementById('test-table').getElementsByTagName('p');

// 先定位ID为'test-div'的节点,再返回其内部所有class包含red的节点:
var reds = document.getElementById('test-div').getElementsByClassName('red');
(1)HTMLCollection 对象

getElementsByTagName() 方法返回 HTMLCollection 对象。返回一组相同的标签。

// x是HTMLCollection 对象
var x = document.getElementsByTagName("p");

// 集合中的元素可以查看长度
document.getElementById("demo").innerHTML = x.length;

// 集合中的元素可以通过下标访问
y = x[1];
(2)NodeList对象

在这里插入图片描述

注意:节点列表不是数组,但是可以使用索引来获取元素。节点列表无法使用数组的方法: valueOf(), pop(), push(), 或 join() 。

2、通过CSS里的选择器selector

使用这个可以不用一层一层的确定最后的元素位置

// 通过querySelector获取ID为q1的节点  -- 选择一个节点
var q1 = documnet.querySelector('#q1');
// 通过querySelectorAll()获取q1节点内的符合条件的所有节点
var ps = q1.querySelectorALL('div.highlighted > p');

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

二、修改DOM节点 – 改变 HTML 元素的内容和样式

更新操作是指修改节点的文本或者是HTML的结构

1、修改HTML的内容

(1)innerHTML属性

不但可以修改一个DOM节点的文本内容,还可以直接通过HTML片段修改DOM节点内部的子树(如果写入的字符串是通过网络拿到的,要注意对字符编码来避免XSS攻击。)

// 获取节点<p id="p-id"></p>
var p = document.getElementById('p-id');
// 修改文本为abc -- 可以直接在HTML里写文字,但是这是通过js去控制的. --   <p id="p-id">ABC</p>
p.innerHTML = 'ABC'; 
// 修改HTML的结构  -- 在p标签里添加span标签
p.innerHTML = 'ABC <span style="color:red">RED</span>XYZ';
(2)innerText 或 textContent 属性

这个属性可以自动对字符串进行HTML编码,保证无法设置任何HTML标签 – 即不能改变HTML的结构

p.innerText = 'ABC'; 

2、修改HTML的样式 – css

由于DOM节点的属性对应所有的CSS,故可以通过style标签修改。

document.getElementById("p2").style.color="blue";

三、插入DOM元素 – 如何添加或删除 HTML 元素

向文档中添加和移除元素

1、innerHTML – 父节点为空的情况

// 使用innerHTML修改HTML的结构 -- 即插入新的节点
p.innerHTML = '<span>child</span>';

2、父节点不空

(1)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>
// 将已有的节点插入
// 取节点
var js = document.getElementById('js'),
    list = document.getElementById('list');
list.appendChild(js);
// 创建新的节点插入  -- <p id="haskell">Haskell</p>
var list = document.getElementById('list'),
    // 创建p标签
    haskell = document.createElement('p');
// 为新的p标签指定id和内容
haskell.id = 'haskell';
haskell.innerText = 'Haskell';
list.appendChild(haskell);
(2) insertBefore() – 插入到指定位置
// 插入到python之前
var list = document.getElementById('list'),
    ref = document.getElementById('python');
list.insertBefore(haskell,ref);

四、删除和替换HTML元素

1、删除HTML元素 – removeChild()

要删除一个节点,首先要获得该节点本身以及它的父节点,然后,调用父节点的removeChild把自己删掉.注意到删除后的节点虽然不在文档树中了,但其实它还在内存中,可以随时再次被添加到别的位置。

// 得到父节点和删除的节点
var children = document.getElementById('to-be-removed');
var parent = children.parentElement;
parent.removeChild(children);

2、替换HTML元素 – replaceChild()

var parent = document.getElementById("div1");
var child = document.getElementById("p1");
// 用para节点替换child节点
parent.replaceChild(para, child);

五、DOM的children属性

(1)遍历父节点的所有子节点 – children属性

var 
	i,c,
    list = document.getElementByTd('list');
for(i=0; i<list.children.length;i++){
    c = list.children[i];
}

(2)children属性是一个只读属性,并且它在子节点变化时会实时更新。

var parent = document.getElementById('parent');
parent.removeChild(parent.children[0]);
// <-- 浏览器报错,因为删除一个节点之后,节点的数量变成了1
parent.removeChild(parent.children[1]); 

六、DOM事件 – 对 HTML DOM 事件作出反应

1、事件

HTML事件是发生在HTML元素上的事情。当在页面中使用JavaScript时,JS可以触发这些事件。事件可以是浏览器行为,也可以是用户的行为。 JavaScript 与HTML之间的交互是通过事件实现的。

// 在HTML元素中添加事件属性,当事情发生的时候JS就会做出反应。
// 按钮元素中添加了 onclick 属性。当点击元素这个事件发生的时候,将修改id="demo" 元素的内容。
<button onclick="getElementById('demo').innerHTML=Date()">现在的时间是?</button>

2、事件属性

(1)向HTML元素分配属性

// 点击事件属性onclick
<button onclick="displayDate()">点击</button>

(2)使用HTML DOM分配单个事件

<button id="myBtn">点这里</button>
<script>
document.getElementById("myBtn").onclick=function(){displayDate()};
</script>

(3)事件类型

在这里插入图片描述

3、HTML DOM EventListener – 可以分配多个事件句柄

  • 当你使用 addEventListener() 方法时, JavaScript 从 HTML 标记中分离开来,可读性更强, 在没有控制HTML标记时也可以添加事件监听。
  • 你可以向一个元素添加多个相同的或者不同的事件句柄。
  • 你可以向同个元素添加多个同类型的事件句柄,如:两个 “click” 事件。且不会覆盖已存在的事件
  • 你可以向任何 DOM 对象添加事件监听,不仅仅是 HTML 元素。如: window 对象。
(1)addEventListener() 方法
// element.addEventListener(event, function, useCapture);
// 第一个参数是事件的类型 (如 "click" 或 "mousedown").
// 第二个参数是事件触发后调用的函数。
// 第三个参数是个布尔值用于描述事件是冒泡还是捕获。该参数是可选的。
document.getElementById("myBtn").addEventListener("click", displayDate);
(2)向同一个元素中添加多个事件句柄
element.addEventListener("click", myFunction);
element.addEventListener("click", mySecondFunction);
(3)事件的传递 – 冒泡与捕获

在这里插入图片描述

(4)事件的移除 – removeEventListener
element.removeEventListener("mousemove", myFunction);