DOM基础语法
DOM基础语法
1、 简介
文档对象模型(DOM),是 W3C 组织推荐的处理可扩展标记语言(HTML、XML)的标准编程接口
W3C 已经定义了一系列 DOM 接口,通过这些 DOM 接口可以改变网页的内容、结构和样式
1.1 DOM树

文档:一个页面就是一个文档,DOM 中使用 document 表示
元素:页面中的所有标签都是元素,DOM 中使用 element 表示
节点:网页中的所有内容都是节点(标签、属性、文本、注释等),DOM 中使用 node 表示
DOM把以上内容都看做是对象
2、 获取元素
获取页面中的元素可以使用一下几种方式
- 根据 id 获取
- 根据标签名获取
- 通过 HTML5 新增的方法获取
- 特殊元素获取
2.1 根据 id 获取
使用 getElementById("id")
方法可以获取带有 id 的元素对象
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div id="time"> 2022-2-1</div> <script> var time = document.getElementById("time"); // 大小写敏感 console.log(typeof time); console.dir(time); console.log(time); // console.dir() 打印我们返回的元素对象,更好的查看里面的属性和方法 </script> </body> </html>
- 因为我们的文档页面从上往下加载,所以先得有标签,故我们 script 写到标签的下面
- get 获得 element 元素 by 通过 驼峰命名法
- 参数 id 是大小写敏感的字符串
- 返回的是一个元素对象
2.2 根据标签名获取
使用getElementsByTagName("标签名")
方法可以返回带有指定标签名的对象集合
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <ul> <li>123 a</li> <li>123 b</li> <li>123 c</li> <li>123 d</li> <li>123 e</li> </ul> <script> var lis = document.getElementsByTagName("li"); console.log(lis); console.log(lis[0]); for (var i = 0; i < lis.length(); i++){ console.log(lis[i]) } </script> </body> </html>
- 返回的是获取过来元素对象的集合,以伪数组的形式存储,遍历获取数据
- 得到的元素是动态的
- 如果页面中没有这个元素,放回的伪数组是一个空数组
2.3 根据标签名获取
使用element.getElementByTagName("标签名")
获取某个元素(父元素)内部所有指定标签名的子元素
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <ul> <li>123 a</li> <li>123 b</li> <li>123 c</li> <li>123 d</li> <li>123 e</li> </ul> <ol id="first"> <li>23 a</li> <li>23 b</li> <li>23 c</li> <li>23 d</li> <li>23 e</li> </ol> <script> var ol1 = document.getElementById("first"); // var ol1 = document.getElementsByTagName("ol")[0] 效果一样 var lis = ol1.getElementsByTagName("li"); // 一定要指明那个父元素 console.log(lis); console.log(lis[0]); </script> </body> </html>
父元素必须是单个对象(必须指明是哪个元素对象)获取的时候不包括父元素自己
2.4 根据 类名来获取
使用document.getElementsByClassName("类名")
来获取元素对象集合
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div class="box">盒子1</div> <div class="box">盒子2</div> <script> var boxs = document.getElementsByClassName("box"); console.log(boxs); </script> </body> </html>
2.5 通过指定选择器获取
使用document.querySelector("选择器")
指定选择器,获取第一个元素对象
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div class="box">盒子1</div> <div class="box">盒子2</div> <div id="f1">盒子3</div> <script> var box = document.querySelector("div"); console.log(box); var id = document.querySelector("#f1"); // 使用id选择 // 如果使用类选择器,则 (".box") console.log(id); </script> </body> </html>
使用document.querySelectorAll("选择器")
指定选择器,获取所有的元素
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div class="box">盒子1</div> <div class="box">盒子2</div> <div id="f1">盒子3</div> <script> var boxs = document.querySelectorAll(".box"); console.log(boxs); </script> </body> </html>
2.6 获取 body 和 html 元素
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> // body var bodyEle = document.body; console.log(bodyEle); console.dir(bodyEle); // html var htmlEle = document.documentElement; console.log(htmlEle); </script> </body> </html>
3、 事件基础
3.1 概述
JS 使我们有能力创建动态页面,而事件是可以被 JS 侦测到的行为
简单理解:触发 --- 响应机制
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <button id="btn">hello</button> <script> btn.onclick = function() { alert("hello world"); } </script> </body> </html>
- 事件是有三部分组成:事件源、事件类型、事件处理程序;也称事件三要素
- 事件源:事件被触发的对象
- 事件类型:如何触发,什么事件,如:鼠标点击、鼠标经过还是键盘按下
- 事件处理程序:通过一个函数赋值的方式完成
3.2 事件执行步骤
- 获取事件源
- 注册事件(绑定事件)
- 添加事件处理程序(采取函数赋值形式)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div>点我</div> <script> // 获取事件源 var div = document.querySelector("div"); // 绑定事件,并且添加事件处理程序 div.onclick = function(){ alert("你好呀!") } </script> </body> </html>
3.3 常见的鼠标事件
鼠标事件 | 触发条件 |
---|---|
onclick | 单击 |
ondblclick | 双击 |
onmousedown | 鼠标上的按钮被按下触发的事件 |
onmouseup | 鼠标按下后,松开时触发的事件 |
onmouseover | 鼠标悬浮 |
onmousemove | 鼠标移动 |
onmouseenter | 鼠标进入 |
onmouseleave | 鼠标离开 |
onfocus | 鼠标焦点 |
onblur | 失去鼠标焦点 |
4、 操作元素
JS 的 DOM 操作可以改变网页的内容、结构和样式,我们可以利用 DOM 操作元素来改变元素里面的内容、属性等
4.1 改变元素内容
element.innerText; // 从起始位置到终止位置的内容,当它不包括html标签,同时空格和换行也会换掉 element.innerHTML; // 起始位置到终止位置的全部内容,包括html标签,同时保留空格和换行
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <button>显示当前时间</button> <div>时间显示</div> <script> var btn = document.querySelector("button"); // 获取对象 var div = document.querySelector("div"); // 获取div btn.onclick = function(){ // 定义事件 var date = new Date(); var year = date.getFullYear(); var month = date.getMonth() + 1; var data = date.getDate(); var hour = date.getHours(); var mit = date.getMinutes(); var sec = date.getSeconds(); div.innerText = year.toString() + "-" + month.toString() + "-" + data.toString() + '\n' + hour.toString() + ":" + mit.toString() + ":" + sec.toString(); // 修改文本 } </script> </body> </html>
- innerText 和 innerHTML 的区别
- innerText 不识别HTML标签,而 innerHTML 则识别
- innerText 会去除换行和空格
4.2 改变元素属性
直接赋值即可
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <button id="btn1">百度</button> <button id="btn2">qq</button> <a href="https://www.baidu.com">使用百度</a> <script> var btn1 = document.querySelector("#btn1"), // 获取按钮1 btn2 = document.querySelector("#btn2"), link = document.querySelector("a"); btn1.onclick = function(){ link.href = "https://www.baidu.com"; // 修改属性 link.innerText = "使用百度"; } btn2.onclick = function(){ link.href = "https://www.qq.com"; link.innerText = "使用qq"; } </script> </body> </html>
4.3 表单元素属性操作
利用 DOM 可以操作如下表单元素的属性
type / value / checked / selected / disabled
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <button>按钮</button> <input type="text" placeholder="请输入内容"> <script> var btn = document.querySelector("button"); var ipt = document.querySelector("input"); // 定义事件 btn.onclick = function(){ ipt.value = "你好呀!" // input 表单专门使用 value 来修改 btn.disabled = true; // 点击按钮后禁用,也可以用于表单禁用 // 也可以使用 this.disabled = true; 来实现按钮的禁用 this指向的是函数的调用者 } </script> </body> </html>
显示密码
- 点击按钮,把密码框的类型改为文本框就可以看见里面的代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <button>按钮</button> <input type="password" placeholder="请输入密码"> <script> var btn = document.querySelector("button"); var ipt = document.querySelector("input"); // 定义事件 var flag = 0; btn.onclick = function(flag){ flag++; if (flag % 2 === 0 ){ ipt.type = "password"; } else{ ipt.type = "text"; } } </script> </body> </html>
4.4 样式属性操作
我们可以通过 JS 修改元素的大小、颜色、位置等样式
element.style 行内样式属性操作 element.style.cssText 多个行内样式的修改 element.className 类名样式操作
4.4.1 行内样式
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> #div { width: 200px; height: 200px; background-color: pink; } </style> </head> <body> <div id="div">你好</div> <script> var div = document.querySelector("#div"); div.onclick = function() { // 行内 div.style.backgroundColor = "purple"; // 属性采取驼峰命名法 this.style.height = "100px"; } div.ondblclick = function() { // 行内多个修改 this.style.cssText = "background-color: red; height: 30px"; } </script> </body> </html>
注意
- JS 里面的样式采取驼峰命名法
- 多个修改里面每个单词使用
-
隔开- JS 修改 style 样式操作,产生的是行内样式,CSS 权重比较高
- 样式比较少或者功能简单的情况下使用
4.4.2 类名样式
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> #div { width: 200px; height: 200px; background-color: pink; } .change { background-color: purple; color: red; font-size: large; margin: 100px; } </style> </head> <body> <div id="div">文本</div> <script> var div = document.querySelector("#div"); div.onclick = function() { this.className = 'change'; // 让我们当前元素的类名改为了 change } </script> </body> </html>
注意
className 会直接更改元素的类名,会覆盖原先的类名
可以通过修改元素的 className 更改元素的样式,适合于样式较多或者功能复杂的情况
如果想要保留原先的类名,我们可以这么做
this.className = "原先的类名 change";
4.5 排他思想
如果有同一组元素,我们想要某一个元素实现某个样式,需要用到循环的排他思想算法
- 所有元素全部清除样式
- 给当前元素设置样式
- 注意顺序不能颠倒
4.6 表单全选与取消全选
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> .wrap > table > thead { background-color: rgb(22, 99, 102); } .wrap > table{ margin: 100px auto; } </style> </head> <body> <div class="wrap"> <table border="1" cellspacing="0" cellpadding="3px"> <thead> <tr> <th> <input type="checkbox" id="j_cbAll"> </th> <th>goods</th> <th>price</th> </tr> </thead> <tbody id="j_tb"> <tr> <td><input type="checkbox"></td> <td>iPhone8</td> <td>8000</td> </tr> <tr> <td><input type="checkbox"></td> <td>iPad Pro</td> <td>5000</td> </tr> <tr> <td><input type="checkbox"></td> <td>iPad Air</td> <td>2000</td> </tr> <tr> <td><input type="checkbox"></td> <td>Apple Watch</td> <td>2000</td> </tr> </tbody> </table> </div> <script> var j_cbAll = document.getElementById("j_cbAll"); var j_tbs = document.getElementById("j_tb").getElementsByTagName("input"); j_cbAll.onclick = function(){ for (var i = 0; i < j_tbs.length; i++){ j_tbs[i].checked = this.checked; // this.checked 表示选中 } } for (var i = 0; i < j_tbs.length; i++){ j_tbs[i].onclick = function(){ // flag 控制全选按钮是否选中 var flag = true; // 循环检查按钮是否全部被选择 for (var j = 0; j < j_tbs.length; j++ ){ if (!j_tbs[j].checked){ // 如果有没有选中的 flag = false; break; } } j_cbAll.checked = flag; // 当为false时,会不勾选 } } </script> </body> </html>
4.7 自定义属性操作
4.7.1 获取属性值
element.属性
:获取属性值element.getAttribute("属性")
:获取属性值
<div class="cls"></div> <script> var div1 = document.querySelector("div"); console.log(div1.class); console.log(div1.getAttribute("class")); </script>
区别
element.属性
获取内置属性值(元素本身自带的属性)element.getAttribute("属性")
主要获得自定义的属性(标准)我们程序员自定义的属性
4.7.2 设置属性值
element.属性 = "值"
设置内置属性值element.setAttribute("属性", "值")
设置属性值
4.7.3 移除属性
element.removeAttribute("属性")
移除属性
4.8 H5自定义元素
自定义元素的目的:是为了保存并使用数据。有些数据可以保存到页面中二不用保存到数据库中
自定义属性获取是通过getAttribute("属性")
获取
但是有些自定义属性容易引起歧义,不容易判断是元素的内置属性还是自定义属性
H5 给我们新增了自定义属性
4.8.1 设置H5自定义属性
H5 规定自定义属性, data 开头作为属性名并且赋值
比如:
<div data-index="1"></div>
4.8.2 获取H5自定义属性
-
兼容性获取
element.getAttribute("属性名")
-
新增方法
element.dataset.属性
/element.dataset["属性名"]
var div1 = document.querySelector("div"); console.log(div1.dataset.index); console.log(div1.dataset["index"]); // dataset 是一个集合,里面存放了所有以data开头的自定义属性
5、 节点操作
5.1 为什么要学节点操作
获取元素通常使用两种方式
- 利用 DOM 提供的方法获取元素
- 逻辑性不强、繁琐
- 利用节点层级关系获取元素
- 利用父子兄弟节点关系获取元素
- 逻辑性强,但是兼容性较差
5.2 节点概述
网页中的所有内容都是节点(标签、属性、文本、注释等),在 DOM 中,节点使用 node 表示
HTML DOM 树中的所有节点均可以通过 JS 进行访问,所有 HTML 元素(节点)均可被修改,也可以创建或删除
一般的,节点至少拥有 nodeType(节点类型)、nodeName(节点名称)和 nodeValue(节点值)这三个基本属性
- 我们在实际开发中,节点操作的主要是元素节点
5.3 节点层级
利用 [DOM 树](#1.1 DOM树)可以把节点划分为不同层级关系,常见的是父子兄层级关系
5.3.1 父级节点
node.parentNode;
<div id="box"> <span class="erweima"></span> </div> <script> var erweima = document.querySelector(".erweima"); var box = erweima.parentNode; // 得到父节点 </script>
得到的是离元素最近的父级节点
如果指定的节点没有父节点则返回 null
5.3.2 子节点
node.childNodes; // 标准 // 得到的是指定子节点的集合,该集合为及时更新的集合 node.firstChild; // 第一个子节点 node.lastChild; // 最后一个子节点
<body> <ul> <li>节点1</li> <li>节点2</li> <li>节点3</li> <li>节点4</li> <li>节点5</li> </ul> <script> var ul = document.querySelector("ul"); var lis = ul.childNodes; console.log(lis); console.log(lis[0].nodeType); console.log(lis[1].nodeType); </script> </body>
子节点,childNodes 所有的子节点,包含元素节点、文本节点等
如果只想获得里面的元素节点,则需要专门处理。所以我们一般不提倡使用 childNodes
var ul = document.querySelector("ul"); for (var i = 0; i < ul.childNodes.length; i++) { if (ul.child[i].nodeType == 1) { // 其为元素节点 console.log(ul.childNodes[i]); } }
node.children; // 非标准 // 其是一个只读属性,返回的子元素节点。它返回子元素节点,其余节点不返回 node.firstElementChild; // 第一个子元素节点 node.lastElementChild; // 最后一个子元素节点 // 找不到返回null
console.log(ul.children);
返回伪数组
5.3.3 兄弟节点
node.nextSibling; // 返回当前元素的下一个兄弟节点,找不到返回null;其包含所有的节点 node.previousSibling; // 返回当前元素的上一个元素的兄弟节点,找不到则返回null;同样,也是包含所有节点 node.nextElementSibling; // 返回当前元素下一个兄弟元素节点,找不到返回null node.previousElementSibling; // 返回当前元素上一个兄弟元素节点,找不到返回null
5.4 创建节点
document.createElement("tagName"); // 创建节点
document.createElement()
方法创建由 tagName 指定的 HTML 元素。因为这些元素原先不存在,是根据我们的需求动态生成的,所以我们也称为动态创建元素节点
5.5 添加节点
node.appendChild(child);
node.appendChild() 方法将一个节点添加到指定父元素的子节点列表末尾。类似于 CSS 里面的 after 伪元素
<body> <ul> <li>1</li> </ul> <script> // 创建节点 var li1 = document.createElement("li"); // 添加节点 node 父级 child 子级 后面追加元素 var ul = document.querySelector("ul"); ul.appendChild(li1); </script> </body>
node.insertBefore(child, 指定元素);
将一个节点添加到父节点的指定子节点前面,类似于 css 里面的 before 伪元素
5.6 发布留言案例
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> ul > li { background-color: rgb(18, 143, 160); /* 背景颜色 */ margin-top: 10px; /* 外边距 */ list-style-type: none; /* 去除小圆点 */ color: red; /* 文本颜色 */ } </style> </head> <body> <textarea name="" id="" cols="30" rows="10"></textarea> <button>发布</button> <ul> </ul> <script> var btn = document.querySelector("button"); // 获取按钮 var tara = document.querySelector("textarea"); // 获取输入框 var ul = document.querySelector("ul"); // 获取列表 btn.onclick = function() { // 注册事件 console.log(tara.value); if (tara.value == "") { // 但输入框没有内容时 alert("请输入内容!") } else { var lin = document.createElement("li"); // 创建节点 lin.innerHTML = tara.value; // 修改内容 ul.insertBefore(lin, ul.children[0]); // 插入内容 tara.value = ""; // 清除文本框内容 } } </script> </body> </html>
5.7 删除节点
node.removeChild(child); // 从 DOM 中删除一个子节点,返回删除
var btn = document.querySelector("button"); // 获取按钮 var ul = document.querySelector("ul"); // 获取列表 btn.onclick = function() { // 注册事件 if (ul.children.length === 0){ alert("里面没有内容!"); this.disabled = true; // 按钮被禁用 } else { ul.removeChild(ul.children[(ul.children.length - 1)]); console.log(ul.removeChild(ul.children[(ul.children.length - 1)])); // 返回被删除的内容 } }
5.8 创建评论框
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> ul > li { background-color: rgb(18, 143, 160); /* 背景颜色 */ margin-top: 10px; /* 外边距 */ list-style-type: none; /* 去除小圆点 */ color: red; /* 文本颜色 */ width: 300px; } li > a { text-decoration: none; color: black; float: right; font-size: 12px; line-height: 20.8px; } </style> </head> <body> <textarea name="" id="" cols="30" rows="10" placeholder="请输入评论"></textarea> <button>发布评论</button> <ul style="padding: 2px;"> </ul> <script> var btn = document.querySelector("button"); // 获取按钮 var tara = document.querySelector("textarea"); // 获取输入框 var ul = document.querySelector("ul"); // 获取列表 btn.onclick = function() { // 注册事件 if (tara.value == "") { // 但输入框没有内容时 alert("请输入内容!") } else { var lin = document.createElement("li"); // 创建节点 lin.innerHTML = tara.value + "<a href='javascript:;'>删除评论</a>"; // javascript:; 或者 javascript: void(0); 阻止链接跳转 ul.insertBefore(lin, ul.children[0]); // 插入内容 tara.value = ""; // 清除文本框内容 // 删除元素 var dul = document.querySelectorAll("a"); for (var i = 0; i < dul.length; i++) { dul[i].onclick = function() { ul.removeChild(this.parentNode); // 删除li标签 } } } } </script> </body> </html>
5.9 复制节点
node.cloneNode()
:复制节点
其返回调用该方法的一个副本,也称为克隆节点 / 拷贝节点
<body> <ul> <li>1</li> <li>2</li> <li>3</li> </ul> <script> var ul = document.querySelector("ul"); var li = ul.children[0].cloneNode(); // 只有标签,没有内容 var lc = ul.children[0].cloneNode(true); // 包括内容 ul.firstElementChild.appendChild(li); ul.firstElementChild.appendChild(lc); </script> </body>
- 如果括号内参数为空或为 false,其为浅拷贝,即只克隆复制节点本身,不克隆里面的子节点
- 如果括号参数为 true,则是深度拷贝,会复制节点本身以及里面所有的子节点
5.10 动态生成表格
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> td > a { text-decoration: none; color: red; } table { width: 500px; margin: 100px auto; border-collapse: collapse; text-align: center; } td, th { border: 1px solid #333; } thead tr { height: 40px; background-color: #ccc; } </style> </head> <body> <table> <thead> <tr> <th>姓名</th> <th>科目</th> <th>成绩</th> <th>操作</th> </tr> </thead> <tbody> </tbody> </table> <script> // 准备数据 var db = { name: "李华", subject: "JavaScript", score: 100 } var dbs = [ { name: "李四", subject: "JavaScript", score: 20 } ]; // 存放数据 dbs[dbs.length] = db; // 添加数据 var tbody = document.querySelector("tbody"); for (var i = 0; i < dbs.length; i++) { // 向tbody里面添加数据 // 创建元素 var tr = document.createElement("tr"); tbody.appendChild(tr); // 创建单元格--跟数据有关系的单元格 for (var j in dbs[i]) { // 遍历对象 var td = document.createElement("td"); tr.appendChild(td); td.innerText = dbs[i][j]; // 属性值 } // 创建有删除的单元格 var td = document.createElement("td"); tr.appendChild(td); td.innerHTML = "<a href='javascript:;'> 删除 </a>"; } // 注册删除事件 var as = tbody.querySelectorAll("a"); for (var i = 0; i < as.length; i++) { as[i].onclick = function() { // 点击删除,删除整行内容 tbody.removeChild(this.parentNode.parentNode); } } </script> </body> </html>
5.11 三种动态创建元素的区别
-
document.write ( )
-
document.write("<div>123</div>"); -
在页面文档流加载完毕,直接将内容写入页面的内容流,则它会覆盖原来页面的内容
-
-
element.innerHTML
- 其是将内容写入某个 DOM 节点,不会导致页面全部重绘
- 其创建多个元素效率更高(使用数组形式拼接时),结构稍微复杂
-
document.createElement ( )
- 创建多个元素效率稍微低一点点,但是结构更清晰
6、 DOM 重点核心
文档对象模型,是 W3C 组织推荐的处理可扩展标记语言的标准编程接口
W3C 已经定义了一系列的 DOM 接口,通过这些 DOM 接口可以改变网页的内容、结构和样式
- 对于JS ,为了能够使 JS 操作 HTML ,JS 就有了一套自己的 DOM 接口
- 对于 HTML 来说,DOM 使得 HTML 形成一颗 DOM 树,包含文档、元素、节点
- 我们获取过来的 DOM 元素是一个对象,所以称为文档对象模型
关于 DOM 操作,我们主要针对元素的操作。主要有创建、删除、修改、查找、增加、事件操作
6.1 创建
document.write(); innnerHTML; document.createElement();
6.2 增加
node.appendChild(); node.insertBefore();
6.3 删除
node.removeChild();
6.4 修改
主要修改 DOM 元素属性,DOM 元素的内容、属性,表单的值等
- 修改元素属性:src、href、title 等
- 修改普通元素内容;innerHTML、innerText
- 修改表单元素:value、type、disabled 等
- 修改元素样式:style、className、style.cssText 等
6.5 查找
主要获取查询 DOM 的元素
- DOM 提供 API 方法:getElementById、getElementsByTagName 等,古老用法不太推荐
- H5 提供的新方法:querySelector、querySelectorAll 推荐
- 利用节点操作获取元素:父(parentNode)、子(children)、兄(previousElementSibling / nextElementSiblling) 推荐
6.6 属性操作
主要针对自定义属性
- setAttribute:设置 DOM 的属性值
- getAttribute:得到 DOM 的属性值
- removeAttribute:移除属性
6.7 事件操作
给元素注册事件,采取事件源、事件类型 = 事件处理程序
7、 事件高级
7.1 注册事件
给元素添加事件,称为注册事件或者绑定事件
注册事件有两种方式:传统方式和方法监听注方式
7.1.1 传统注册
利用 on 开头的事件 onclick
-
<button onclick="alert('hello~')"></button> -
btn.onclick = function() {} -
特点
- 注册事件的唯一性
- 同一个元素同一个事件只能设置一个处理函数,最后注册的处理函数将会覆盖前面注册的函数
7.1.2 事件监听注册
W3C 标准推荐方式
addEventListener() // 是一个方法 // IE9 以前的IE不支持此方法,可使用 attachEvent() 代替
特点
- 同一个元素同一个事件可以注册多个监听器
7.1.2.1 addEventListener
eventTarget.addEventListener(type, listener [, useCapture]); // 该方法将指定的监听器注册到 eventTarget 上,当该对象触发指定的事件时,就会执行事件处理函数
参数
- type:事件类型字符串,比如 click、mouseover 等,注意这里不要带 on
- listener:事件处理函数,事件发生时,会调用该监听函数
- useCapture:可选参数,是一个布尔值,默认是 false
<body> <button id="eventLisetener">警告</button> <script> btn = document.getElementById("eventLisetener"); btn.addEventListener("click", function() { // 里面的事件类型是字符串,必定加引号,而且不带on alert("hi~"); }) btn.addEventListener("click", function() { // 可以重复注册 alert("hello~"); }) </script> </body>
7.1.2.2 attachEvent
eventTarget.attachEvent(eventNameWithOn, callback); // 该方法将指定的监听器注册到 eventTarget 上,当该对象触发指定事件时,指定的回调函数就会执行
参数
- eventNameWithOn:事件类型字符串,比如 onclick、onmouseover 等,这里要带 on
- callback:事件处理函数,当目标触发事件时回调函数被调用
<body> <button id="eventLisetener">警告</button> <script> btn = document.getElementById("eventLisetener"); btn.attachEvent("onclick", function() { alert("我是老方法哦!") // IE9 版本以前的才支持 }) </script> </body>
7.2 删除事件
7.2.1 传统事件
eventTarget.onclick = null;
// 传统绑定事件 // div[0].onclick = fn; div[0].onclick = function() { alert("传统方式注册事件"); div[0].onclick = null; // 删除事件 }
7.2.2 事件监听
7.2.2.1 removeEventListener
eventTarget.removeEventListener(type, listener [, useCapture]);
div[1].addEventListener("click", fn); // 里面的fn不需要调用加小括号 function fn() { // 定义事件函数 alert("这是一个事件函数"); // 移除事件 div[1].removeEventListener("click", fn); }
7.2.2.2 detachEvent
eventTarget.detachEvent(eventNameWithOn, callbackk);
div[2].attachEvent("onclick", fn); function fn() { alert("我是老方法哦!") // IE9 版本以前的才支持 // 移除事件 div[2].detachEvent("onclick", fn); }
7.3 DOM 事件流
事件流描述的是从页面中接收事件的顺序
事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程即 DOM 事件流

DOM 事件流分为三个阶段
- 事件捕获阶段
- 网景最早提出,由 DOM 最顶层节点开始,然后逐级向下传播到具体的元素接收的过程
- 当前目标阶段
- 事件冒泡阶段
- 事件冒泡:IE 最早提出,事件开始时由最具体的元素接收,然后逐级向上传播到 DOM 最顶层节点的过程
注意
-
JS 代码中只能执行捕获或者冒泡其中的一个阶段
-
传统事件和 attachEvent 只能的到冒泡阶段
-
addEventListener 第三个参数如果是 true ,表示在事件捕获阶段调用事件处理程序;如果是 false (默认为 false),表示在事件冒泡阶段调用事件处理程序
-
捕获阶段
-
<div class="father" style="width: 120px; height: 120px; background-color: blue;"> <div class="son" style="width: 100px; height: 100px; background-color: red;"></div> </div> <script> // 捕获阶段,如果 addEventListener 第三个参数是 true ,那么则处于捕获阶段 document -> html -> body -> father -> son var son = document.querySelector(".son"); son.addEventListener("click", function() { alert("son"); // 先执行 father 再 son }, true); son.parentElement.addEventListener("click", function() { alert("father"); }, true)
-
-
冒泡阶段
-
<div class="father" style="width: 120px; height: 120px; background-color: blue;"> <div class="son" style="width: 100px; height: 100px; background-color: red;"></div> </div> <script> // 冒泡阶段,如果 addEventListener 第三个参数是 false ,那么则处于冒泡阶段 son -> father -> body -> html -> document var son = document.querySelector(".son"); son.addEventListener("click", function() { alert("son"); // 先执行 son 再执行 father }); son.parentElement.addEventListener("click", function() { alert("father"); });
-
-
-
在实际开发中,我们很少使用事件捕获,我们更关注事件冒泡
-
有些事件是没有冒泡的,比如 onblur、onfocus、onmouseenter、onmouseleave
7.4 事件对象
<div style="border: 1px solid black; border-radius: 1px; width: 30px; height: 30px; background-color: aquamarine;">123</div> <script> var div = document.querySelector("div"); div.onclick = function(event) { /* 1、 event 就是一个事件对象写到我们监听函数的小括号里面,当形参来看 2、 事件对象只有有了事件才会存在,它是系统自动创建的,不需要我们传递参数 3、 事件对象是我们事件的一系列相关数据的集合,跟事件相关的,比如鼠标点击事件里面就包括了鼠标的相关信息(鼠标坐标等),键盘事件里面就包含了键盘事件的信息(用户按下哪个键等) 4、 这个事件对象我们可以自己命名 5、 事件对象也有兼容性问题 ie9 通过 window.event,兼容性写法 event = event || window.event; */ console.log(event); } </script>
简单理解:事件发生后。跟事件相关的一系列信息数据集合都存放到这个对象里面,这个对象就是事件对象 event ,它有很多属性和方法
这个 event 是个形参,系统帮我们设定为事件对象,不需要传递实参过去
当我们注册事件时,event 对象就会被系统自动创建,并依次传递给事件监听器(事件处理函数)
7.4.1 事件对象的属性和方法
事件对象属性方法 | 说明 |
---|---|
event.target | 返回触发事件的对象(标准) |
event.srcElement | 放回触发事件的对象(非标) |
event.type | 返回事件的类型 |
event.cancelBubble | 该属性阻止冒泡的进行(非标) |
event.stopPropagation() | 阻止冒泡 (标准) |
event.returnValue | 该属性阻止默认事件(默认行为)(非标)比如不让链接跳转 |
event.preventDefault() | 该方法阻止默认事件(默认行为)(标准) |
7.4.1.1 target 和 this 的区别
<div>123</div> <ul> <li>abc</li> <li>abc</li> <li>abc</li> </ul> <script> var div = document.querySelector("div"); var ul = document.querySelector("ul"); div.addEventListener("click", function(event) { console.log(event.target); console.log(this); }) ul.addEventListener("click", function(event) { console.log(event.target); // 返回点击的元素 li console.log(this); // 返回 ul,this 指向 ul }) </script>
target:点击了哪个元素,就返回哪个元素
this:哪个元素绑定了这个点击事件,那么久返回哪个元素
7.4.1.2 阻止冒泡
事件冒泡:开始时由最具体的元素接收,然后逐级向上传播到 DOM 最顶层节点
事件冒泡本身的特性,会带来坏处,也会有好处
阻止冒泡
-
标准写法:stopPropagation()
<div class="father" style="width: 120px; height: 120px; background-color: blue;"> <div class="son" style="width: 100px; height: 100px; background-color: red;"></div> </div> <script> var son = document.querySelector(".son"); son.addEventListener("click", function(event) { alert("son"); event.stopPropagation(); }); son.parentElement.addEventListener("click", function() { alert("father"); }); </script> -
非标准写法:cancelBubble (IE9以下)
<div class="father" style="width: 120px; height: 120px; background-color: blue;"> <div class="son" style="width: 100px; height: 100px; background-color: red;"></div> </div> <script> var son = document.querySelector(".son"); son.addEventListener("click", function(event) { alert("son"); event.cancelBubble = true; // 停止冒泡 }); son.parentElement.addEventListener("click", function() { alert("father"); }); </script>
7.5 事件委托
事件委托也称为事件代理,在jQuery里面称为事件委派
原理
- 不是每个子节点单独设置事件监听器,而是事件监听器设置在其父节点上,然后利用冒泡原理影响设置每个子节点
作用
- 我们只操作了一次 DOM ,提高了程序执行的性能
<ul> <li>234</li> <li>234</li> <li>234</li> <li>234</li> <li>234</li> </ul> <script> // 事件委托 var ul = document.querySelector("ul"); ul.addEventListener("click", function(e) { alert("hello~~~"); for (var i = 0; i < ul.children.length; i++) { this.children[i].style.backgroundColor = ""; } e.target.style.backgroundColor = "pink"; }) </script>
7.6 常用的鼠标事件
7.6.1 禁止选中
-
禁止鼠标右键
contextmenu 主要控制应该何时显示上下文菜单,主要用于程序员取消默认上下文菜单
document.addEventListener("contextmenu", function(e) { e.preventDefault(); // 阻止右键菜单 }) -
禁止鼠标选中
selectstart 开始选中
document.addEventListener("selectstart", function(e) { e.preventDefault(); // 阻止选中文字 })
7.6.2 鼠标事件对象
event 对象代表事件的状态,跟事件相关的一系列信息的集合
MouseEvent
和键盘事件对象 KeyboardEvent
鼠标事件对象 | 说明 |
---|---|
e.clientX | 返回鼠标相对于浏览器窗口可视区的X坐标 |
e.clientY | 返回鼠标相对于浏览器窗口可视区的Y坐标 |
e.pageX | 返回鼠标相对于页面文档的X坐标 IE9+支持 |
e.pageY | 返回鼠标相对于页面文档的Y坐标 IE9+支持 |
e.screenX | 返回鼠标相对于电脑屏幕的X坐标 |
e.screenY | 返回鼠标相对于电脑屏幕的Y坐标 |
7.7 常用的键盘事件
7.7.1 键盘事件
事件除了使用鼠标触发,还可以使用键盘触发
键盘事件 | 触发条件 |
---|---|
onkeyup | 某个键被松开时触发 |
onkeydown | 某个键被按下时触发 |
onkeypress | 某个键被按下时触发,但是它不识别功能键,如:Ctrl 等 |
document.addEventListener("keyup", function(e) { console.log("我起飞了"); }) document.addEventListener("keydown", function() { console.log("我落地了"); }) document.addEventListener("keypress", function() { console.log("我又落地了"); })
三个事件的执行顺序:keydown -> keypress -> keyup
7.7.2 键盘事件对象
keyCode:返回该键的 ASCII 值
document.addEventListener("keyup", function(e) { console.log(e); console.log(e.keyCode); // 得到相应键的ASCII码值 /* 同时,我们的 keyup 和 keydown 事件不区分字母大小写,a 和 A 都为65 keypress事件区分字母大小写,a 为 97、A 为 65 */ })
本文来自博客园,作者:Kenny_LZK,转载请注明原文链接:https://www.cnblogs.com/liuzhongkun/p/15886523.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了