DOM03
目录
前言
DOM03学习开始
一、复习
- DOM:
D
ocumentO
bjectM
odel
- 文档 : HTML代码
- 对象 : HTML代码 会转换成 JS的document对象, 然后再渲染到页面
- 模型 : 代表这套机制
- 查询到要操作的元素
- id
document.getElementById
- 关系
- 父: parentElement
- 子: children
- 兄: previousElementSibling
- 弟: nextElementSibling
- css选择器
querySelector
: 查询单个元素querySelectorAll
: 查询所有元素- 操作元素
- 多个元素: 要遍历 才能操作每个元素
- class相关
- className: 直接操作 class 的本体 --
不推荐
- classList: 一个存放了操作 class 方法的属性
- add : 添加
- remove: 删除
toggle: 切换
二、style
<!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>style 09:08</title> </head> <body> <!-- style: 内联样式, 直接修改单个标签, 优先级最高 --> <!-- class: 样式类, 依赖选择器可以大面积修改样式 --> <!-- style: 支持动态变更样式的值 --> <button>变大</button> <p>Hello World!</p> <script> const btn = document.querySelector('button') btn.onclick = function () { const p = this.nextElementSibling console.dir(p) //查看style属性 // 获取p标签当前的字体大小 +1 再设置给 fontSize // getComputedStyle: 获取元素当前的样式 // 元素的样式由 3种元素决定: style class 默认设定 const curStyle = getComputedStyle(p) // '16px' -> 16 p.style.fontSize = parseInt(curStyle.fontSize) + 1 + 'px' } </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>练习 09:27</title> <style> #box { width: 10px; height: 30px; background-color: orange; border-radius: 4px; } </style> </head> <body> <button>变大</button> <div id="box"></div> <script> const btn = document.querySelector('button') btn.onclick = function () { const box = this.nextElementSibling const w = getComputedStyle(box).width box.style.width = parseInt(w) + 1 + 'px' } // setInterval(() => { // btn.onclick() // }, 1000 / 60); </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>轮播图 09:47</title> <link rel="stylesheet" href="./reset.css"> <style> #banner { width: 500px; height: 230px; /* border: 2px solid red; */ position: relative; overflow: hidden; } #banner>.navigator { position: absolute; top: 50%; transform: translateY(-50%); /* border: 2px solid blue; */ width: 100%; display: flex; justify-content: space-between; padding: 0 6px; } #banner>.slides { display: flex; height: 100%; width: 100%; /* margin-left: -100%; */ /* transform: translateX(-100%); */ position: absolute; left: -000%; transition: 0.3s; } #banner img { width: 100%; height: 100%; } #banner>.indicator { display: flex; position: absolute; bottom: 10px; left: 50%; transform: translateX(-50%); } #banner>.indicator>span { width: 12px; height: 12px; background-color: white; border-radius: 50%; margin: 0 3px; cursor: pointer; } #banner>.indicator>span.active { background-color: #0ca4ec; } </style> </head> <body> <div id="banner"> <div class="slides"> <img src="./imgs/banner1.png" alt=""> <img src="./imgs/banner2.png" alt=""> <img src="./imgs/banner3.png" alt=""> <img src="./imgs/banner4.png" alt=""> </div> <div class="navigator"> <button>上一页</button> <button>下一页</button> </div> <div class="indicator"> <span class="active"></span> <span></span> <span></span> <span></span> </div> </div> <script> // 1. 鼠标悬浮在哪个小圆点, 就高亮; 其他不高亮 const indicators = document.querySelectorAll('#banner>.indicator>span') const slides = document.querySelector('#banner>.slides') console.log(indicators) indicators.forEach(el => { el.onmouseover = function () { document.querySelector('#banner .active').classList.remove('active') this.classList.add('active') // 利用数组的indexOf方法, 临时放到 小圆点数组里, 求当前小圆点的序号 // 较为常见: 伪数组太多, 经常需要把数组的方法 临时放到伪数组中执行 // 相当于 indicators.indexOf(this) const i = Array.prototype.indexOf.call(indicators, this) console.log('i', i) slides.style.left = `-${i}00%` } }) // 下一页: // 思路: 点击按钮后, 找到当前激活的小圆点的 下一个小圆点, 触发其鼠标悬浮方法 const btn_next = document.querySelector('#banner button:last-child') btn_next.onclick = function () { var ac = document.querySelector('#banner .active') //当前 var next = ac.nextElementSibling // 如果next不存在, 说明当前是最后一个, 则应该回到第一项 if (!next) { // 找所有兄弟元素的方式: 先找父 -> 孩子们 next = ac.parentElement.children[0] } next.onmouseover() // 编程式 触发事件相关方法 } // 上一页: const btn_prev = document.querySelector('#banner button:first-child') btn_prev.onclick = function () { var ac = document.querySelector('#banner .active') var prev = ac.previousElementSibling if (!prev) { var children = ac.parentElement.children // 最后一个的序号: 数组长度 - 1 prev = children[children.length - 1] } prev.onmouseover() } // 自动滚动: 每隔3秒, 就通过代码方式, 触发 下一页按钮的 点击事件 setInterval(() => { btn_next.onclick() }, 3000); </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>图片的src属性</title> </head> <body> <!-- 网页上的元素, 主要 文字和图 + 音频 视频 --> <!-- 图片通过 src 属性, 来设置显示的内容地址 --> <button>切换图片</button> <img src="./imgs/bigskin-1.jpg" height="200" alt=""> <script> const btn = document.querySelector('button') btn.onclick = function () { var img = this.nextElementSibling console.dir(img) // 查看其 src 属性 // 修改 src 属性的值, 图片会重新渲染 img.src = './imgs/bigskin-3.jpg' } </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>练习 14:02</title> <link rel="stylesheet" href="./reset.css"> <style> #box { width: 1000px; position: relative; } #box>ul { position: absolute; right: 50px; bottom: 10px; display: flex; flex-direction: row-reverse; cursor: pointer; } #box>ul>li { color: white; margin-right: 10px; font-size: 14px; display: flex; flex-direction: column; align-items: flex-end; } #box>ul>li>img { border-radius: 0 15px; border: 4px solid #7a7a7a; } #box>ul>li.active>img { border-color: #f3c258; } #box>img { width: 100%; } </style> </head> <body> <div id="box"> <img src="./imgs/bigskin-5.jpg" alt=""> <ul> <li> <img src="./imgs/smallskin-1.jpg" alt=""> <span>鹿灵守心</span> </li> <li> <img src="./imgs/smallskin-2.jpg" alt=""> <span>森 </span> </li> <li> <img src="./imgs/smallskin-3.jpg" alt=""> <span>遇见神鹿</span> </li> <li> <img src="./imgs/smallskin-4.jpg" alt=""> <span>时之祈愿</span> </li> <li class="active"> <img src="./imgs/smallskin-5.jpg" alt=""> <span>时之愿境</span> </li> </ul> </div> <script> const lis = document.querySelectorAll('#box li') // 存放大图地址 const big_imgs = [ './imgs/bigskin-1.jpg', './imgs/bigskin-2.jpg', './imgs/bigskin-3.jpg', './imgs/bigskin-4.jpg', './imgs/bigskin-5.jpg', ] const big_img = document.querySelector('#box>img') lis.forEach(li => { li.onmouseover = function () { // 以前: 找到激活的, 去掉其激活样式 // 另一个思路: 把每个li 都删除 active 样式 lis.forEach(li => li.classList.remove('active')) this.classList.add('active') // 获取当前激活项目的序号 var i = Array.prototype.indexOf.call(lis, this) console.log(i) // 通过序号 获取路径, 设置给大图 big_img.src = big_imgs[i] } }) </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>自定义属性 15:16</title> </head> <body> <!-- 属性: property 或 attribute --> <!-- DOM元素的属性分 2 类 --> <!-- 1. 系统属性: 官方设计提供, 各有各的用途 2. 自定义属性: 用户添加 2.1 (不推荐) 随便书写属性名, 不要和官方的冲突 2.2 (推荐) 用 data- 开头 --> <img data-x="10" data-y="20" data-SunKai="孙凯" data-YA-NAN="楠楠" sui="随" bian="便" src="./imgs/1_lg.jpg" alt="大图1" id="img1"> <script> const img1 = document.getElementById('img1') console.dir(img1) // 系统属性: 可以直接通过属性名来操作 console.log(img1.src, img1.alt); img1.src = './imgs/banner1.png' img1.alt = '新的图片' // 自定义: // 规范的方式: data- // 存储在 dataset 属性里 // 命名规范: 破折线语法 会转 小驼峰语法 -- 首个单词全小写, 后续首字母大写 console.log(img1.dataset.x, img1.dataset.y); img1.dataset.sunkai = '凯凯' // 自定义的非规范写法 // 通过打印 无法直接看到, 必须通过指定的方法来读取 // get:获取 attribute:属性 var sui = img1.getAttribute('sui') var bian = img1.getAttribute('bian') console.log(sui, bian) // 修改 img1.setAttribute('sui', '哈哈哈') </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>练习 14:46</title> <link rel="stylesheet" href="./reset.css"> <style> #box>ul { display: flex; } #box>ul img { width: 80px; border: 4px solid transparent; } #box>ul>li.active>img { border-color: orange; } </style> </head> <body> <div id="box"> <img src="./imgs/1_lg.jpg" alt=""> <ul> <!-- 直接把大图地址, 存放在元素上 --> <li data-big="./imgs/1_lg.jpg" class="active"><img src="./imgs/1_sm.jpg" alt=""></li> <li data-big="./imgs/2_lg.jpg"><img src="./imgs/2_sm.jpg" alt=""></li> <li data-big="./imgs/3_lg.jpg"><img src="./imgs/3_sm.jpg" alt=""></li> <li data-big="./imgs/4_lg.jpg"><img src="./imgs/4_sm.jpg" alt=""></li> <li data-big="./imgs/5_lg.jpg"><img src="./imgs/5_sm.jpg" alt=""></li> </ul> </div> <script> const lis = document.querySelectorAll('#box li') const big_img = document.querySelector('#box>img') lis.forEach(li => { li.onmouseover = function () { lis.forEach(li => li.classList.remove('active')) this.classList.add('active') // 大图的src 等于 自定义属性中的 big 的值 big_img.src = this.dataset.big } }) </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>标签内容 16:26</title> </head> <body> <div id="box1">Hello World</div> <div id="box2"> <a href="">Hello World</a> </div> <script> const box1 = document.getElementById('box1') const box2 = document.getElementById('box2') // innerText: 读取文本部分的内容 // innerHTML: 读取 文本 + HTML标签 + 换行符 + 空格 等.. 所有HTML代码 console.dir(box1) console.dir(box2) // 写入时: box1.innerHTML = '<h1>Hello</h1>' //作为HTML代码解析后显示 box2.innerText = '<h1>Hello</h1>' //作为普通文本显示, 不解析 </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>练习 16:38</title> </head> <body> <div id="box"> <button>-</button> <span>5</span> <button>+</button> </div> <script> // 利用 数组解构 语法, 把子元素拿出来存储在 a b c 变量中 const [a, b, c] = document.getElementById('box').children c.onclick = function () { b.innerHTML++ a.disabled = false // 不可用为假 不不可用 } // 减按钮 a.onclick = function () { b.innerHTML-- // 值是1, 则减按钮 不可用 是真 if (b.innerHTML == 1) a.disabled = true } </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>练习 16:51</title> <link rel="stylesheet" href="./reset.css"> <style> table { min-width: 500px; } td { padding: 5px; } </style> </head> <body> <table border="1"> <thead> <tr> <td>名称</td> <td>单价</td> <td>数量</td> <td>小计</td> </tr> </thead> <tbody> <tr> <td>苹果</td> <td>9</td> <td> <button disabled>-</button> <span>1</span> <button>+</button> </td> <td>9</td> </tr> </tbody> </table> <script> const tr = document.querySelector('tbody>tr') // 习惯用 $ 前缀来区分 普通的数值 和 元素类型的值 // 第一个逗号: 不解构第一个值, 用来间隔 const [, $price, $count, $total] = tr.children const [$btn_jian, $num, $btn_jia] = $count.children $btn_jia.onclick = function () { $num.innerHTML++ $btn_jian.disabled = false $total.innerHTML = $num.innerHTML * $price.innerHTML } $btn_jian.onclick = function () { $num.innerHTML-- if ($num.innerHTML == 1) $btn_jian.disabled = true $total.innerHTML = $num.innerHTML * $price.innerHTML } </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>购物车 17:34</title> <link rel="stylesheet" href="./reset.css"> <style> table { min-width: 500px; } td { padding: 5px; } </style> </head> <body> <table border="1"> <thead> <tr> <td>名称</td> <td>单价</td> <td>数量</td> <td>小计</td> </tr> </thead> <tbody> <tr> <td>苹果</td> <td>9</td> <td> <button disabled>-</button> <span>1</span> <button>+</button> </td> <td>9</td> </tr> <tr> <td>柿子</td> <td>13</td> <td> <button disabled>-</button> <span>1</span> <button>+</button> </td> <td>13</td> </tr> <tr> <td>葡萄</td> <td>19</td> <td> <button>-</button> <span>10</span> <button>+</button> </td> <td>190</td> </tr> <tr> <td>香蕉</td> <td>6</td> <td> <button>-</button> <span>3</span> <button>+</button> </td> <td>18</td> </tr> </tbody> <tfoot> <tr> <td colspan="4">总计: 230</td> </tr> </tfoot> </table> <script> const trs = document.querySelectorAll('tbody>tr') trs.forEach(tr => { const [, $price, $count, $total] = tr.children const [$b1, $num, $b2] = $count.children $b2.onclick = function () { $num.innerHTML++ $b1.disabled = false $total.innerHTML = $price.innerHTML * $num.innerHTML } $b1.onclick = function () { $num.innerHTML-- if ($num.innerHTML == 1) $b1.disabled = true $total.innerHTML = $price.innerHTML * $num.innerHTML } }) </script> </body> </html>
总结
- style: 内联样式
- 适合: 样式动态变更的场景
- 方法:
getComputedStyle
- 获取元素的当前样式
- 元素的样式由
内联样式
+class
+默认的自带样式
三种合并后决定- 图片的src属性
- 修改这个属性, 可以刷新图片
- 属性
- 系统属性
- 自定义属性
- 正规:
data-
(存储在dataset
属性里)- 非正规(1.getAttribute : 读取 。2.setAttribute : 设置 )
- 内容
- innerText
- 读取文本
- 设置 文本内容
- innerHTM
- 读取HTML代码内容
- 设置的内容, 会做为HTML解析后显示