【笔记】JS的浏览器API的DOM学习笔记

前言

JS的浏览器应用程序编程接口(Application Programming Interface, API)的文档对象模型(Document Object Model, DOM)学习笔记
文档对象模型(英语:Document Object Model,缩写DOM),是W3C组织推荐的处理可扩展置标语言和超文本标记语言的标准编程接口。(维基百科
浏览器将HTML元素树(HTML Tree)抽象称为了JS对象树(DOM Tree),浏览器提供了通过JS操作HTML元素的API

获取元素

获取文档

1
document;
1
<html></html>

写入文档

1
document.write("<div></div>");

通过document对象获取body

1
document.body;
1
<body></body>

通过document对象获取head

1
document.head;
1
<head></head>

通过document对象获取任意元素

根据标签名获取元素

  • 可以在元素上调用
  • 增删元素会实时更新
1
<div></div>
1
var elementList = document.getElementsByTagName("div");
获取所有标签名
1
var elementList = document.getElementsByTagName("*");

根据id获取元素

  • 不能在元素上调用
  • 增删元素不会实时更新
1
<div id="key"></div>
1
var element = document.getElementById("key");

根据class获取元素

  • 可以在元素上调用
  • 增删元素会实时更新
1
<div class="key"></div>
1
var elementList = document.getElementsByClassName("key");

根据name获取元素

  • 不能在元素上调用
  • 增删元素会实时更新
1
<input name="key">
1
var elementList = document.getElementsByName("key");

通过CSS选择器获取元素

  • 可以在元素上调用

  • 增删元素不会实时更新

  • 获取单个元素

1
var element = document.querySelector("#key");
  • 获取多个元素
1
var elementList = document.querySelectorAll(".key");
  • 遍历可迭代对象
1
2
3
for (var i = 0; i < elementList.length; i++) {
console.log(elementList[i]);
}
1
2
3
for (var item of elementList) {
console.log(item);
}

继承结构

graph TD
    EventTarget[EventTarget] --> Node[Node]
    Node --> Document[Document]
    Node --> Element[Element]
    Node --> CharacterData[CharacterData]
    Node --> DocumentFragment[DocumentFragment]
    Node --> Attr[Attr]
    Node --> CDATASection[CDATASection]
    Node --> ProcessingInstruction[ProcessingInstruction]
    Node --> DocumentType[DocumentType]
    Node --> ShadowRoot[ShadowRoot]
    Document --> HTMLDocument[HTMLDocument]
    Document --> XMLDocument[XMLDocument]
    Element --> HTMLElement[HTMLElement]
    HTMLElement --> HTMLDivElement[HTMLDivElement]
    HTMLElement --> HTMLImageElement[HTMLImageElement]
    CharacterData --> Text[Text]
    CharacterData --> Comment[Comment]
    EventTarget --> Event[Event]
    Event --> CustomEvent[CustomEvent]

对节点相关的操作

获取父节点

1
element.parentNode;

获取兄弟节点

获取哥哥节点

1
element.previousSibling;

获取弟弟节点

1
element.nextSibling;

获取子节点

获取所有子节点

1
element.childNodes;

获取第一个子节点

1
element.firstChild;

获取最后一个子节点

1
element.lastChild;

获取节点的类型

1
node.nodeType;

1Node.ELEMENT_NODE:元素
3Node.TEXT_NODE:文本内容
8Node.COMMENT_NODE:注释
9Node.DOCUMENT_NODE:文档
10Node.DOCUMENT_TYPE_NODE:文档声明

获取节点的名称

1
node.nodeName;

DIV:具体元素
#text:文本内容
#comment:注释

获取非元素的节点的数据

1
node.data;

对元素相关的操作

获取父元素

1
element.parentElement;

获取兄弟元素

获取哥哥元素

1
element.previousElementSibling;

获取弟弟元素

1
element.nextElementSibling;

获取子元素

获取所有子元素

1
element.children;

获取第一个子元素

1
element.firstElementChild;

获取最后一个子元素

1
element.lastElementChild;

获取指定的子元素

根据标签名获取元素
  • 可以在元素上调用
  • 增删元素会实时更新
1
<div></div>
1
var elementList = element.getElementsByTagName("div");
获取所有标签名
1
var elementList = element.getElementsByTagName("*");
根据class获取元素
  • 可以在元素上调用
  • 增删元素会实时更新
1
<div class="key"></div>
1
var elementList = element.getElementsByClassName("key");
通过CSS选择器获取元素
  • 可以在元素上调用
  • 增删元素不会实时更新
获取单个元素
1
var element = element.querySelector("#key");
获取多个元素
1
var elementList = element.querySelectorAll(".key");

#####¥ 遍历可迭代对象

1
2
3
for (var i = 0; i < elementList.length; i++) {
console.log(elementList[i]);
}
1
2
3
for (var item of elementList) {
console.log(item);
}

获取元素的名称

1
element.tagName;

"DIV":具体元素名称

元素的内容

元素内部的HTML

获取元素内部的HTML
1
element.innerHTML;
修改元素内部的HTML
1
element.innerHTML = "<div></div>";

元素外部的HTML

  • 元素自身及元素内部的HTML
获取元素外部的HTML
1
element.outerHTML;
修改元素外部的HTML
1
element.outerHTML = "<div></div>";

元素内部的文本内容

获取元素内部的文本内容
1
element.innerText;
1
element.textContent;
修改元素内部的文本内容
1
element.innerText = "文本内容";
1
element.textContent = "文本内容";

操作元素的HTML标签属性(Attribute)

  • 标准HTML标签属性:由浏览器定义的内置属性

  • 非标准HTML标签属性:由开发者自定义的属性

  • HTML标签属性大小写不敏感

直接操作元素的HTML标签属性(Attribute)

  • 无论是否是标准HTML标签属性,都可以直接操作元素的HTML标签属性

  • 直接通过Attribute方式修改属性时,通过Property方式查询的属性值会随之改变

判断指定属性是否存在
1
var result = element.hasAttribute("属性名");
获取指定属性值
  • 返回的值一定是字符串
1
var result = element.getAttribute("属性名");
  • 如果不存在,则返回null
1
2
3
4
5
6
<div id="key"></div>

<script>
var element = document.getElementById("key");
element.getAttribute("hidden"); // null
</script>
  • 如果是布尔属性,并且没有指定值,则返回空字符串
1
2
3
4
5
6
<div id="key" hidden></div>

<script>
var element = document.getElementById("key");
element.getAttribute("hidden"); // ""
</script>
  • 如果是布尔属性,并且有指定值,则返回对应字符串
1
2
3
4
5
6
<div id="key" hidden="hidden"></div>

<script>
var element = document.getElementById("key");
element.getAttribute("hidden"); // "hidden"
</script>
修改指定属性
1
element.setAttribute("属性名", "值");
删除指定属性
1
element.removeAttribute("属性名");
获取所有属性
1
var result = element.attributes;

通过JS对象属性(Property)操作HTML元素属性(Attribute)

  • 通过Property方式修改属性时,直接通过Attribute方式查询的属性值会随之改变

    • 同时利用Property和Attribute修改属性时,Property优先级会更高
  • 只有标准HTML标签属性可以通过JS对象属性操作HTML元素属性

操作内置的HTML标签属性
获取指定的内置的HTML标签属性值
  • 如果不存在,则返回undefined
1
2
3
4
5
6
<div id="key"></div>

<script>
var element = document.getElementById("key");
element.hidden; // undefined
</script>
  • 如果是布尔属性,并且没有指定值,则返回true
1
2
3
4
5
6
<div id="key" hidden></div>

<script>
var element = document.getElementById("key");
element.hidden; // true
</script>
  • 如果是布尔属性,并且有指定值,则返回true
1
2
3
4
5
6
<div id="key" hidden="hidden"></div>

<script>
var element = document.getElementById("key");
element.hidden; // true
</script>
操作自定义的HTML标签属性
  • 通过data-作为前缀的自定义属性在映射为JS对象时会放到dataset属性中
1
<div id="key" data-key="value"></div>
获取指定的自定义的HTML标签属性
1
element.dataset.key;
修改指定的自定义的HTML标签属性
1
element.dataset.key = "value";

操作HTML标签属性(Attribute)的样式

  • 操作HTML标签属性(Attribute)的class属性和style属性
操作style
设置单个样式
  • CSS中的属性名通常是以横线命名,映射为JS对象后,JS对象中style的属性是以小驼峰命名
1
element.style.backgroundColor = "red";
  • 如果将属性值设置为空字符串,此时这个属性的值被设置为浏览器默认样式
1
element.style.backgroundColor = "";
设置多个样式
1
element.style.cssText = "background-color: red; color: red;";
获取单个内联样式
  • 如果内联样式中没有定义则不能获取
1
element.style.backgroundColor;
获取单个样式
  • 可以获取任何地方定义的样式
1
getComputedStyle(element).backgroundColor;
操作className
添加或覆盖class
1
element.className = "key";
操作classList
向classList添加class
1
element.classList.add("key");
从classList删除class
1
element.classList.remove("key");
从classList切换class
  • 如果classList中存在class,就删除class
  • 如果classList中不存在class,就添加class
1
element.classList.toggle("key");
判断classList是否存在class
1
element.classList.contains("key");
遍历classList
  • 遍历可迭代对象classList
1
2
3
for (var i = 0; i < element.classList.length; i++) {
console.log(element.classList[i]);
}
1
2
3
for (var classItem of element.classList) {
console.log(classItem);
}

创建元素

div:定义标签名

1
var element = document.createElement("div");

插入元素

  • 在指定元素附近插入元素或字符串
    • 可以插入单个也可以插入多个
    • 可以插入元素或字符串

element:在这个元素附近插入元素
otherElement:被插入的元素

在指定元素的所有子元素最前面插入

1
element.prepend(otherElement);
1
element.prepend("");
1
element.prepend(otherElement, "");

在指定元素的所有子元素最后面插入

1
element.append(otherElement);
1
element.append("");
1
element.append(otherElement, "");

在指定元素之前插入

1
element.before(otherElement);
1
element.before("");
1
element.before(otherElement, "");

在指定元素之后插入

1
element.after(otherElement);
1
element.after("");
1
element.after(otherElement, "");

替换元素

  • 用元素或字符串替换元素

otherElement:被替换的元素

1
element.replaceWith(otherElement);
1
element.replaceWith("");
1
element.replaceWith(otherElement, "");

移除元素

  • 移除当前元素
1
element.remove();

克隆元素

浅克隆

1
var elementNew = element.cloneNode();
1
var elementNew = element.cloneNode(false);

深克隆

1
var elementNew = element.cloneNode(true);

元素的CSS样式

  • -命名改为小驼峰命名

获取CSS样式

1
element.style.backgroundColor;

修改CSS样式

1
element.style.backgroundColor = "red";

元素的尺寸、距离、滚动

获取元素的可视区域尺寸

  • 不包含滚动条,不包含边框尺寸
1
2
element.clientWidth;
element.clientHeight;

获取元素的可视区域完整尺寸

  • 不包含滚动条,包含边框尺寸
1
2
element.offsetWidth;
element.offsetHeight;

获取元素的边框尺寸

1
2
element.clientTop;
element.clientLeft;

获取元素的左上角的距离

  • 包含边框的元素的左上角的距离
1
2
element.offsetTop;
element.offsetLeft;

获取元素的完整内容高度

1
element.scrollHeight;

获取元素的滚动位置

  • 不包含边框的元素的上边缘距离元素的完整内容起始位置的偏移量
1
element.scrollTop;

window的尺寸、距离、滚动

获取window的内容尺寸

  • 不包含滚动条
1
2
document.documentElement.clientWidth;
document.documentElement.clientHeight;

获取window的内容完整尺寸

  • 包含滚动条
1
2
window.innerWidth;
window.innerHeight;

获取window的窗口完整尺寸

  • 包含工具栏和调试工具
1
2
window.outerWidth;
window.outerHeight;

获取window的滚动距离

1
2
window.scrollX;
window.scrollY;
1
2
window.pageXOffset;
window.pageYOffset;

window的滚动操作

滚动至绝对位置

<num_x>:横坐标
<num_y>:纵坐标

1
window.scrollTo(<num_x>, <num_y>);
滚动至相对位置

<num_x>:相对于当前元素的横向偏移量
<num_y>:相对于当前元素的纵向偏移量

1
window.scrollBy(<num_x>, <num_y>);

对表格的额外操作

1
var tableElement = document.getElementByTagName("table")[0];

获取表格一部分

获取表格标题部分

1
tableElement.caption;

获取表格的头部分

1
tableElement.tHead;

获取表格的体部分

  • 获取表格<tbody></tbody>
1
tableElement.tBodies;

获取表格的尾部分

1
tableElement.tFoot;

获取当前部分的所有行

  • 获取当前部分的所有<tr></tr>元素
1
var trElementList = tableElement.rows;
1
var trElementList = table.tHead.rows;
1
var trElementList = tablet.Bodies[0].rows;
1
var trElementList = table.tFoot.rows;

获取当前行的所有格子

  • 获取当前行的所有<th></th>元素和<td></td>元素
1
trElementList[0].cells;

获取行在部分中的索引

  • 获取<tr></tr>元素在<thead></thead><tbody></tbody><tfoot></tfoot>中的索引
1
trElementList[0].sectionRowIndex;

获取行在表格中的索引

  • 获取当前<tr></tr>元素在<table></table>的中所有<tr></tr>列表中的索引
1
trElementList[0].rowIndex;

获取单元格在行中的索引

1
trElementList[0].cells[0].cellIndex;

对表单的额外操作

获取文档中的所有表单

1
var formElementList = document.forms;

获取表单中的所有子元素

1
var formSonElementList = formElementList.elements;

通过子元素name获取子元素

1
2
3
<form>
<input name="key" />
</form>
1
var formSonElement = formElementList.elements["key"];

事件

定义事件

直接在HTML标签上定义事件

1
2
3
4
<div onclick="fn"></div>
<script>
function fn(event) {}
</script>

通过JS对象的属性定义事件

1
element.onclick = function (event) {}

通过JS对象的事件监听器定义事件

冒泡阶段执行
1
element.addEventListener("click", function (event) {});
1
element.addEventListener("click", function (event) {}, false);
捕获阶段执行
1
element.addEventListener("click", function (event) {}, true);

形参event的属性

事件的类型

1
var result = event.type;

发生事件的元素

1
var result = event.target;

处理事件的元素

1
var result = event.currentTarget;

事件所处的阶段

1
var result = event.eventPhase;

结果

1:捕获阶段(Capturing Phase)
2:目标阶段(Target Phase)
3:冒泡阶段(Bubbling Phase)

发生事件时光标的位置

在元素内的位置
1
2
var result = event.offsetX;
var result = event.offsetY;
在客户端的位置
1
2
var result = event.clientX;
var result = event.clientY;
在文档document中的位置
1
2
var result = event.pageX;
var result = event.pageY;
在屏幕screen中的位置
1
2
var result = event.screenX;
var result = event.screenY;

阻止HTML元素默认的事件

1
event.preventDefault();

阻止事件的传递

  • 阻止事件冒泡和传递
1
event.stopPropagation();

EventTarget

  • EventTarget是一个DOM接口,用于新增、删除、派发Event事件

添加事件监听

1
2
3
function fn() {}

element.addEventListener("click", fn);

移除事件监听

  • 通过removeEventListener()方法移除之前添加的事件,传入的函数需要与添加时定义的一致
1
2
3
4
function fn() {}

element.addEventListener("click", fn);
element.removeEventListener("click", fn);

派发事件

创建事件对象
1
var e = new Event("事件名");
立即触发事件
1
element.dispatchEvent(e);

事件委派

  • 在父元素中统一处理子元素触发的事件
1
2
3
4
5
elementFather.addEventListener("click", function (event) {
if (event.target === elementSon) {
...
}
})

自定义事件

定义事件

1
var e = new Event("事件名");

定义监听器

1
element.addEventListener("事件名", function () {});

派发事件

1
window.dispatchEvent(e);

内置事件

  • 所有元素都有对应事件名的on方法
    • 如click事件的方法名为onclick

鼠标事件

左键单击
1
element.addEventListener("click", function () {});
右键单击
  • 右键打开上下文菜单时触发
1
element.addEventListener("contextmenu", function () {});
左键双击
1
element.addEventListener("dblclick", function () {});
按键按下
1
element.addEventListener("mousedown", function () {});
按键松开
1
element.addEventListener("mouseup", function () {});
鼠标移动
1
element.addEventListener("mousemove", function () {});
鼠标移入(支持冒泡)
1
element.addEventListener("mouseover", function () {});
鼠标移出(支持冒泡)
1
element.addEventListener("mouseout", function () {});
鼠标移入(不支持冒泡)
1
element.addEventListener("mouseenter", function () {});
鼠标移出(不支持冒泡)
1
element.addEventListener("mouseleave", function () {});

键盘事件

按键事件判定
按键按下(物理键被按下)
1
element.addEventListener("keydown", function () {});
按键按下(字符被输入)
1
element.addEventListener("keypress", function () {});
按键松开(字符输入结束)
1
element.addEventListener("keyup", function () {});
物理按键判定
通过键码值判定
1
if (event.keyCode === 13) {}
通过字符判定
1
if (event.key === "Enter") {}

表单中的按钮事件

提交表单
1
element.addEventListener("submit", function () {});
重置表单
1
element.addEventListener("reset", function () {});

滚动条事件

滚动条位置发生改变
1
element.addEventListener("scroll", function () {});

window事件

定时器和计时器

定时器

  • 延迟一段时间后执行函数

1000:延迟事件,单位毫秒

1
var timeoutId = setTimeout(function () {}, 1000);

arg1arg2:传递参数

1
var timeoutId = setTimeout(function (arg1, arg2) {}, 1000, arg1, arg2);

计时器

  • 每间隔一段时间就执行一次函数

1000:延迟事件,单位毫秒

1
var timeoutId = setInterval(function () {}, 1000);

arg1arg2:传递参数

1
var timeoutId = setInterval(function (arg1, arg2) {}, 1000, arg1, arg2);

停止定时器或计时器

1
clearTimeout(timeoutId);

完成