目录
DOM
DOM 全称为 Document Object Model.
W3C 标准给我们提供了一系列的函数, 让我们可以操作:
- 网页内容
- 网页结构
- 网页样式
DOM树
一个页面的结构是一个树形结构, 称为 DOM 树.树形结构在数据结构阶段会介绍. 就可以简单理解成类似于 “家谱” 这种结构
页面结构形如:
DOM 树结构形如
获取元素
querySelector
使用 querySelector 能够完全复用前面学过的 CSS 选择器知识, 达到更快捷更精准的方式获取到元素对象.var element = document.querySelector(selectors);
selectors 包含一个或多个要匹配的选择器的 DOM字符串 DOMString 。 该字符串必须是有效的 CSS选择器字符串;如果不是,则引发 SYNTAX_ERR 异常 表示文档中与指定的一组CSS选择器匹配的第一个元素的 html元素 Element 对象. 如果您需要与指定选择器匹配的所有元素的列表,则应该使用 querySelectorAll() 可以在任何元素上调用,不仅仅是 document。 调用这个方法的元素将作为本次查找的根元素
querySelectorAll
使用 querySelectorAll 用法和上面类似事务操作
事件三要素
- 事件源: 哪个元素触发的
- 事件类型: 是点击, 选中, 还是修改?
- 事件处理程序: 进一步如何处理. 往往是一个回调函数.
<button id="btn">点我一下</button> <script> var btn = document.getElementById('btn'); btn.onclick = function () { alert("hello world"); } </script>
btn 按钮就是事件源. 点击就是事件类型 function 这个匿名函数就是事件处理程序 其中 btn.onclick = function() 这个操作称为 注册事件/绑定事件
操作元素
通过
dom对象.属性名
就可以进行操作了获取/修改元素属性
我们简单实现一个图片切换的方法,点击图片可以切换图片
<!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> <img src="1.jpg" alt=""> <script> let img = document.querySelector('img'); img.onclick = function() { console.log(img.src); if (img.src.indexOf('1.jpg') >= 0) { img.src = '2.jpg'; } else if (img.src.indexOf('2.jpg') >= 0) { img.src = '1.jpg'; } } </script> </body> </html>
一个HTML标签里,能写哪些属性,就同样可以通过JS中的DOM对象来获取一样的属性,可以通过console.dir这个方法,打印出一个dom对象的全部属性和值~获取/修改表单元素属性
实现一个全选效果,主要是操作input的checked属性
<body> <input type="checkbox" id="all">我全都要<br> <input type="checkbox" class="girl" >貂蝉<br> <input type="checkbox" class="girl">小乔<br> <input type="checkbox" class="girl">安其拉<br> <input type="checkbox" class="girl">妲己<br> <script> // 1. 先获取到元素 let all = document.querySelector('#all'); let girls = document.querySelectorAll('.girl'); // 2. 给all 注册点击事件 all.onclick = function() { for (let i = 0; i < girls.length; i++) { // all.checked 就是all这个复选框的选中状态 girls[i].checked = all.checked; } } // 3. 针对每个girl 注册点击事件,实现对于all的取消操作 for (let i = 0; i < girls.length; i++) { girls[i].onclick = function() { all.checked = checkGirls(girls); } } function checkGirls(girls) { // 判定是不是所有的 girl 都被选中 for (let i = 0; i < girls.length; i++) { if (!girls[i].checked) { return ''; } } return 'checked'; } </script> </body>
获取/修改元素样式
1.style对应行内样式(直接把样式写到style里面)
2.className/classList(对应内部样式/外部样式)应用了一个/一组CSS类名点击放大字体
<body> <div style="font-size: 20px;">这是一个文本</div> <script> let div = document.querySelector('div'); div.onclick = function() { // 1. 先获取到当前字体的大小 console.log(div.style.fontSize); let fontSize = parseInt(div.style.fontSize); // 2. 在当前字体大小的基础上, 多增加5px fontSize += 5; div.style.fontSize = fontSize + 'px'; } </script> </body>
在HTML中,表示类名的属性就是class,但是在JS里,属性名就变成了className/classList,class在JS中也是一个关键字。如果要修改的样式比较多,通过style就麻烦了,可以直接借助css类来修改
夜间模式(关灯开灯)
<style> .light { background-color: #fff; color: #000; } .dark { background-color: #000; color: #fff; } </style> <div class="light" style="height: 500px">这是一段话</div> <button>关灯</button> let div = document.querySelector('div'); let button = document.querySelector('button'); button.onclick = function() { if (div.className == 'light') { div.className = 'dark'; button.innerHTML = '开灯'; } else if (div.className == 'dark') { div.className == 'light' button.innerHTML = '关灯'; } }
操作节点
新增节点
- 创建
let newDiv = document.createElement('div'); newDiv.id = 'newDiv'; newDiv.className = 'one'; newDiv.innerHTML = 'hello'; console.log(newDiv);
此处创建的节点,并没有挂在dom树上,因此浏览器页面中,是显示不出来的。
2. 把节点挂在dom树上
使用appendChild把节点插入到某个节点的子元素中。let container = document.querySelector('.container'); container.appendChild(newDiv);
删除节点
使用 removeChild 删除子节点
oldChild = element.removeChild(child);
child 为待删除节点 element 为 child 的父节点 返回值为该被删除节点 被删除节点只是从 dom 树被删除了, 但是仍然在内存中, 可以随时加入到 dom 树的其他位 置. 如果上例中的 child节点 不是 element 节点的子节点,则该方法会抛出异常.
案例-猜数字
<!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>猜数字小游戏</title> </head> <body> <button id="resetBtn">重新开始一局游戏</button><br> <span>要猜的数字:</span> <input type="text"> <button id="guessBtn">猜</button><br> <span>结果:</span><span id="result"></span><br> <span>已经猜的次数:</span><span id="guessCount">0</span> <script> // 1. 先把上面需要用到的元素都拿到。 let resetBtn = document.querySelector('#resetBtn'); let input = document.querySelector('input'); let guessBtn = document.querySelector('#guessBtn'); let resultSpan = document.querySelector('#resultSpan'); let guessCountSpan = document.querySelector('#guessCountSpan'); // 2. 生成一个 1 - 100 的随机数字 let toGuess = Math.floor(Math.random() * 100) + 1// 0 - 1 之间的数 console.log(toGuess); // 3. 实现点击 猜 按钮的逻辑 guessBtn.onclick = function() { // 1. 读取到input中的输入的内容,并转换成整数 if (input.value == '') { return; } let curNum = parseInt(input.value); // 2. 判定大小关系,并给出提示 if (curNum < toGuess) { // 低了 resultSpan.innerHTML = '低了'; resultSpan.style.color = 'red'; } else if (curNum > toGuess) { // 高了 resultSpan.innerHTML = '高了'; resultSpan.style.color = 'red'; } else { resultSpan.innerHTML = '猜对了!'; resultSpan.style.color = 'green'; } // 3. 更新猜的次数 let guessCount = parseInt(guessCountSpan.innerHTML); guessCountSpan.innerHTML = guessCount + 1; } // 4. 实现 reset 操作的逻辑(开始新游戏) resetBtn.onclick = function() { // 让页面刷新即可 // location 是和 document并列关系的对象 // location 用来控制页面的链接/地址 location.reload(); } </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>表白墙</title> </head> <body> <div class="container"> <h1>表白墙</h1> <p>输入后点击提交, 会将信息显示在表格中</p> <div class="row"> <span>谁: </span> <input class="edit" type="text"> </div> <div class="row"> <span>对谁: </span> <input class="edit" type="text"> </div> <div class="row"> <span>说什么: </span> <input class="edit" type="text"> </div> <div class="row"> <input type="button" value="提交" class="submit"> </div> </div> <style> * { margin: 0; padding: 0; } .container { width: 400px; margin: 0 auto; } h1 { text-align: center; padding: 20px 0; } p { color: #666; text-align: center; font-size: 14px; padding: 10px 0; } .row { height: 40px; display: flex; justify-content: center; align-items: center; } span { width: 100px; line-height: 40px; } .edit { width: 200px; height: 30px; } .submit { width: 304px; height: 40px; color: white; background-color: orange; border: none; } </style> <script> // 给点击按钮注册点击事件 let submit = document.querySelector('.submit'); submit.onclick = function () { // 1. 获取到编辑框内容 let edits = document.querySelectorAll('.edit'); let from = edits[0].value; let to = edits[1].value; let message = edits[2].value; console.log(from + "," + to + "," + message); if (from == '' || to == '' || message == '') { return; } // 2. 构造 html 元素 let row = document.createElement('div'); row.className = 'row'; row.innerHTML = from + '对' + to + '说: ' + message; // 3. 把构造好的元素添加进去 let container = document.querySelector('.container'); container.appendChild(row); // 4. 同时清理之前输入框的内容 for (var i = 0; i < 3; i++) { edits[i].value = ''; } } </script> </body> </html>