JavaScript DOM
文章目录
一、DOW 概念
DOW,全程 Docuemnt Object Model,是 W3C(万维网联盟)的标准,中文释义为 文档对象模型,用于操作文档对象,也就是 访问 和 处理 HTML 文档,通过 DOM ,可以访问所有的 HTML 元素,包括元素的文本和属性,在 HTML 文档中一切皆对象
注意:HTML DOM 独立于平台和编程语言,可以被任何编程语言使用,也就是说,除了JavaScript外,还能用Python、java 等编程语言来使用 DOM
二、DOM 文档树🎄
HTML DOM 被构造为 对象 的树,每个分支都是一个 对象节点
小生不才,做了张图用于理解
DOM 可以👇
- 改变页面中的所有 HTMl 元素(增删改查)
- 改变页面中的所有 HTML 属性值
- 设置页面中的所有 CSS 样式
- 可以对页面中所有的事件 做出响应
节点类型
节点类型 | 英文名 | 描述 |
---|---|---|
元素节点 | Element node | HTML 中的 元素 |
文本节点 | Text node | 标签中的文字,包括标签之间的空格、换行 |
属性节点 | Attribute node | 标签中的属性 |
HTML 文档中的内容大多数都是由文本提供,内容的价值最高
获取节点
根据ID获取元素节点
ID只会有一个,能直接获取到对应的元素
var boxNodes = document.getElementById("box"); // 获取ID名为 box 的节点
根据标签名获取标签节点
要注意的是,网页中相同的标签通常不会只有一个,因此获取到的标签节点是个集合,我们需要去选择所需要标签的索引
var pNodes = document.getElementsByTagName("p")[0]; // 获取的一个p标签节点
获取节点为空现象
如果在获取某一个节点时,返回的内容为空,而 HTML 文档中确实又有这个节点,可就是获取不到
这是因为 HTML 是通过 从上到下,自左到右 的顺序加载内容,如果 JS 比需要获取的节点先行动加载的话,就会出现这种现象。
解决方法
- 通过 window.setTimeout() 方法,在指定的毫秒数后执行指定代码,这相当于 异步 操作,在DOM 获取指定节点执行时, 需要获取的节点 已经加载完毕
- 使用 window.onload 属性,在文件加载过程结束的时候触发,此时可以保证 需要获取的节点 已经加载完毕 『 此方法有缺陷 』
- 将 JS 放到 HTML 文档的最后面 导入
window.setTimeout() 方法
window.setTimeout(function () {
var boxNode = document.getElementById("box"); // 获取ID名为box的节点
}, 2000); // 两秒之后执行,单位为毫秒
window.onload 属性
window.onload = function () {
var boxNode = document.getElementById("box");
console.log(boxNode);
};
window.onload 会有个问题,因为其是个属性,如果多次赋值,会由 写在最下面的赋值 替换掉 之前所写的赋值,产生覆盖现象,这可不是一个好方法
// 未执行
window.onload = function () {
var boxNode = document.getElementById("box"); // 第一次使用 onload
console.log(boxNode);
};
// 只执行了下面的方法
window.onload = function () {
var box1Node = document.getElementById("box_1"); // 最后一次使用 onload
console.log(box1Node);
};
将 JS 放到 HTML 文档的最后面 导入
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>标题</title>
</head>
<body>
<div id="box">
<p id="p-1">我是一个段落</p>
</div>
</body>
</html>
<script type="text/javascript" src="js/index.js"></script>
查找节点
父、子和兄弟节点👇
- DOM 文档树中,最顶部的 Document 节点被称为 根(root)
- 除了 根节点 外,每个节点都有父节点,
- 一个节点可以拥有多个子节点,也可以拥有多个相同父节点的兄弟节点
获取子节点的同时,会把文本节点也给获取到,通过过滤子节点集合来处理这个问题,将此功能封装成函数
获取所有子节点
function get_childNodes(fatherNode) {
// 去除文本元素(空白折叠),获取所有子节点
var nodes = fatherNode.childNodes;
var arr = []; // 保存已经获取的元素节点对象
for (var i = 0; i < nodes.length; i++) {
if (nodes[i].nodeType === 1) {
arr.push(nodes[i]);
}
}
return arr;
}
获取下一节点
function get_nextSibling(Nodes) {
// 去除文本元素(空白折叠),返回真实的下一个兄弟节点
var nextNodes = Nodes.nextSibling;
while (nextNodes && nextNodes.nodeType !== 1) {
nextNodes = nextNodes.nextSibling;
}
return nextNodes;
}
获取上一节点
function get_previousSibling(Nodes) {
// 去除文本元素(空白折叠),返回真实的上一个兄弟节点
var previousNodes = Nodes.previousSibling;
while (previousNodes && previousNodes.nodeType !== 1){
previousNodes = previousNodes.previousSibling;
}
return previousNodes;
}
获取父节点
var pareNode = document.getElementById("Nodes").parentNode;
操作节点(增删改查)✍
创建节点
创建元素节点
document.createElement 方法
var newNode = document.createElement("p"); // 创建了一个 p 标签节点
创建文本节点
document.createTextNode 方法
var textNode = document.createTextNode("hello js");
创建属性节点
document.createAttribute() 方法
var attr = document.createAttribute("align");
attr.value = "center";
插入节点
.appendChild() 方法
- .appendChild() 方法可向在 同一父节点中 的 所有兄弟节点 最后面添加一个 新的子节点
- innerHTML 属性 可以设置 或则 返回 元素的内容
var boxNode = document.getElementById("box"); // 获取ID名为box的节点
var newNode = document.createElement("p"); // 创建一个新的p节点
// 方法一:创建一个文本节点并插入到p节点中
// newNode.appendChild(document.createTextNode("我是插入p标签的文本内容"));
newNode.innerHTML = "我是插入p标签的文本内容"; // 方法二:使用innerHTML属性设置元素内容
boxNode.appendChild(newNode);
.insertBefore(newnode, existingnode) 方法
- 以同一父节点中的子节点为参考点 在此之前插入一个新的子元素
var getNode = document.getElementById("box");
var newNode = document.createElement("p"); // 新的p标签节点
newNode.innerHTML = "我是插入p标签的文本内容";
getNode.insertBefore(newNode, getNode.lastChild);
删除节点
.removeChild() 方法
删除一个子元素
var getNode = document.getElementById("box");
getNode.removeChild(getNode.childNodes[1]); // 将第二个子元素删除
替换节点
.replaceChild(newnode, oldnode) 方法
将某个子节点替换为另一个
var getNode = document.getElementById("box");
var newNode = document.createElement("p");
newNode.innerHTML = "新的p标签";
getNode.replaceChild(newNode, getNode.childNodes[1]); // 将第二个子元素替换掉
节点属性、方法
三个重要属性
-
NodeName 节点的名称
- 元素节点的 nodeName 与其标签名相同
- 属性节点的 nodeName 与属性名相同
- 文本节点的 nodeName 始终是 #text
- 注释节点的 nodeName 始终是是 #comment
- 文档节点的 nodeName 永远是 #document
-
NodeValue 节点的值
- 元素节点的 nodeValue 是 undefined 或 null
- 文本节点的 nodeValue 是文本本身
- 属性节点的 nodeValue 是属性的值
-
NodeType 节点的类型
元素类型 节点类型(NodeType) 元素 1 属性 2 文本 3 注释 8 文档 9 注意:Html 标签的 nodeName 为大写字母
获取指定属性
.getAttribute() 方法
返回指定元素的属性值
var getNode = document.getElementById("box");
console.log(getNode.getAttribute("title")); // 获取 title 属性,获取不到为Null
设置节点属性
.setAttribute(name, value) 方法
设置 或 改变 指定属性并指定值
var getNode = document.getElementById("box");
console.log(getNode.setAttribute("title", "设置节点属性")); // 获取 title 属性,获取不到为Null
设置样式
.style 属性
以 『 .style.样式名 = 样式值 设置样式 』 形式设置样式
如 要莫个节点 设置背景颜色
getNode.style.backgroundColor = "teal";
事件
用户在浏览 HTML 网页时,做了什么操作,比如说点击了网页的某个地方,在表单中输入了内容,等等这些行为,都是 DOM 中的事件
事件三要素:
-
事件源 :要被触发的对象
-
事件:做了什么触发了这个事件、行为
-
事件处理程序:发生了什么事情
生活中的例子: 我要开机玩游戏,对着电脑(事件源)摁下开机键(事件),电脑开机了(事件处理程序)
放到 JS DOM 中:
事件源.事件 = function () {
事件处理程序;
};
事件 | 描述 |
---|---|
onclick | 鼠标单击 |
ondblclick | 鼠标双击 |
onchange | 文本内容或下拉菜单中的选项发生改变 |
onmouseover | 鼠标悬停,即鼠标停留在图片等的上方 |
onmouseout | 鼠标移出,即离开图片等所在的区域 |
onreset | 表单重置时触发 |
事件 | 描述 |
---|---|
onfocus | 获得焦点,表示文本框等获得鼠标光标 |
onblur | 失去焦点,表示文本框等失去鼠标光标 |
onselect | 用户选取文本时触发(和) |
onchange | 该事件在表单元素的内容改变时触发( , , , 和 ) |
oninput | 元素获取用户输入时触发 |
onsubmit | 表单提交事件 |
事件 | 描述 |
---|---|
onload | 网页文档加载事件 |
onunload | 关闭网页时 |
鼠标单击时触发
HTML
<div id="box">
<p>不要点我</p>
</div>
CSS
#box{
width: 500px;
height: 250px;
border: 1px solid black;
background-color: orange;
margin: 50px auto 0;
}
#box>p{
font-size: 25px;
font-weight: bold;
line-height: 250px;
text-align: center;
}
JS
var getNode = document.getElementById("box");
getNode.onclick = function () {
alert("点到我了");
};
参考资料
这些资料都很赞,十分感谢所给我带来的启发,让我学有所得
- JavaScript HTML DOM 菜鸟教程 JavaScript
- JavaScript 和 HTML DOM 参考手册 W3Cschool
- HTML DOM 教程 W3Cschool
由衷感谢💖