• 前端JavaScript入门到精通,javascript核心进阶ES6语法、API、js高级等基础知识和实战 —— Web APIs(三)


    思维导图

    全选案例

    大按钮控制小按钮

    小按钮控制大按钮

    css伪类选择器checked

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
    6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
    7. <title>Documenttitle>
    8. <style>
    9. /* 选择被勾选的复选框 */
    10. .ck:checked {
    11. width: 20px;
    12. height: 20px;
    13. }
    14. style>
    15. head>
    16. <body>
    17. <input type="checkbox" name="" id="" class="ck">
    18. <input type="checkbox" name="" id="" class="ck">
    19. <input type="checkbox" name="" id="" class="ck">
    20. <input type="checkbox" name="" id="" class="ck">
    21. body>
    22. html>

    勾选变大

    重点:

    完整代码:

    1. html>
    2. <html>
    3. <head lang="en">
    4. <meta charset="UTF-8">
    5. <title>title>
    6. <style>
    7. * {
    8. margin: 0;
    9. padding: 0;
    10. }
    11. table {
    12. border-collapse: collapse;
    13. border-spacing: 0;
    14. border: 1px solid #c0c0c0;
    15. width: 500px;
    16. margin: 100px auto;
    17. text-align: center;
    18. }
    19. th {
    20. background-color: #09c;
    21. font: bold 16px "微软雅黑";
    22. color: #fff;
    23. height: 24px;
    24. }
    25. td {
    26. border: 1px solid #d0d0d0;
    27. color: #404060;
    28. padding: 10px;
    29. }
    30. .allCheck {
    31. width: 80px;
    32. }
    33. style>
    34. head>
    35. <body>
    36. <table>
    37. <tr>
    38. <th class="allCheck">
    39. <input type="checkbox" name="" id="checkAll"> <span class="all">全选span>
    40. th>
    41. <th>商品th>
    42. <th>商家th>
    43. <th>价格th>
    44. tr>
    45. <tr>
    46. <td>
    47. <input type="checkbox" name="check" class="ck">
    48. td>
    49. <td>小米手机td>
    50. <td>小米td>
    51. <td>¥1999td>
    52. tr>
    53. <tr>
    54. <td>
    55. <input type="checkbox" name="check" class="ck">
    56. td>
    57. <td>小米净水器td>
    58. <td>小米td>
    59. <td>¥4999td>
    60. tr>
    61. <tr>
    62. <td>
    63. <input type="checkbox" name="check" class="ck">
    64. td>
    65. <td>小米电视td>
    66. <td>小米td>
    67. <td>¥5999td>
    68. tr>
    69. table>
    70. <script>
    71. // 1. 获取大复选框
    72. const checkAll = document.querySelector('#checkAll')
    73. // 2. 获取所有的小复选框
    74. const cks = document.querySelectorAll('.ck')
    75. // 3. 点击大复选框 注册事件
    76. checkAll.addEventListener('click', function () {
    77. // 得到当前大复选框的选中状态
    78. // console.log(checkAll.checked) // 得到 是 true 或者是 false
    79. // 4. 遍历所有的小复选框 让小复选框的checked = 大复选框的 checked
    80. for (let i = 0; i < cks.length; i++) {
    81. cks[i].checked = this.checked
    82. }
    83. })
    84. // 5. 小复选框控制大复选框
    85. for (let i = 0; i < cks.length; i++) {
    86. // 5.1 给所有的小复选框添加点击事件
    87. cks[i].addEventListener('click', function () {
    88. // 判断选中的小复选框个数 是不是等于 总的小复选框个数
    89. // 一定要写到点击里面,因为每次要获得最新的个数
    90. // console.log(document.querySelectorAll('.ck:checked').length)
    91. // console.log(document.querySelectorAll('.ck:checked').length === cks.length)
    92. checkAll.checked = document.querySelectorAll('.ck:checked').length === cks.length
    93. })
    94. }
    95. script>
    96. body>
    97. html>

    Dom事件进阶

    一、事件流

    1.1 事件流和两个阶段说明

    1.2 事件捕获

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
    6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
    7. <title>Documenttitle>
    8. <style>
    9. .father {
    10. width: 500px;
    11. height: 500px;
    12. background-color: pink;
    13. }
    14. .son {
    15. width: 200px;
    16. height: 200px;
    17. background-color: purple;
    18. }
    19. style>
    20. head>
    21. <body>
    22. <div class="father">
    23. <div class="son">div>
    24. div>
    25. <script>
    26. const fa = document.querySelector('.father')
    27. const son = document.querySelector('.son')
    28. // 山东 济南 蓝翔 目标(pink老师) 捕获阶段
    29. // 蓝翔 济南 山东 冒泡阶段
    30. document.addEventListener('click', function () {
    31. alert('我是爷爷')
    32. }, true)
    33. fa.addEventListener('click', function () {
    34. alert('我是爸爸')
    35. }, true)
    36. son.addEventListener('click', function () {
    37. alert('我是儿子')
    38. }, true)
    39. script>
    40. body>
    41. html>

    1.3 事件冒泡

    1.4 阻止冒泡

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
    6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
    7. <title>Documenttitle>
    8. <style>
    9. .father {
    10. width: 500px;
    11. height: 500px;
    12. background-color: pink;
    13. }
    14. .son {
    15. width: 200px;
    16. height: 200px;
    17. background-color: purple;
    18. }
    19. style>
    20. head>
    21. <body>
    22. <div class="father">
    23. <div class="son">div>
    24. div>
    25. <script>
    26. const fa = document.querySelector('.father')
    27. const son = document.querySelector('.son')
    28. // 山东 济南 蓝翔 目标(pink老师) 捕获阶段
    29. // 蓝翔 济南 山东 冒泡阶段
    30. document.addEventListener('click', function () {
    31. alert('我是爷爷')
    32. })
    33. fa.addEventListener('click', function () {
    34. alert('我是爸爸')
    35. })
    36. son.addEventListener('click', function (e) {
    37. alert('我是儿子')
    38. // 组织流动传播 事件对象.stopPropagation()
    39. e.stopPropagation()
    40. })
    41. script>
    42. body>
    43. html>

    1.4.2 阻止默认行为

    1.5 解绑事件

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
    6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
    7. <title>Documenttitle>
    8. head>
    9. <body>
    10. <button>点击button>
    11. <script>
    12. const btn = document.querySelector('button')
    13. // btn.onclick = function () {
    14. // alert('点击了')
    15. // // L0 事件移除解绑
    16. // btn.onclick = null
    17. // }
    18. function fn() {
    19. alert('点击了')
    20. }
    21. btn.addEventListener('click', fn)
    22. // L2 事件移除解绑
    23. btn.removeEventListener('click', fn)
    24. script>
    25. body>
    26. html>

    鼠标经过事件的区别

    使用mouseover会有冒泡效果,当鼠标移动到子元素会触发mouseout事件,然后再由子元素冒泡还会触发mouseover事件。

    但使用mouseenter无冒泡效果,且当鼠标进过子元素不会触发mouseleave事件,只有完全离开父元素才会触发mouseleave事件。

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
    6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
    7. <title>Documenttitle>
    8. <style>
    9. .dad {
    10. width: 400px;
    11. height: 400px;
    12. background-color: pink;
    13. }
    14. .baby {
    15. width: 200px;
    16. height: 200px;
    17. background-color: purple;
    18. }
    19. style>
    20. head>
    21. <body>
    22. <div class="dad">
    23. <div class="baby">div>
    24. div>
    25. <script>
    26. const dad = document.querySelector('.dad')
    27. const baby = document.querySelector('.baby')
    28. dad.addEventListener('mouseenter', function () {
    29. console.log('鼠标经过')
    30. })
    31. dad.addEventListener('mouseleave', function () {
    32. console.log('鼠标离开')
    33. })
    34. script>
    35. body>
    36. html>

    两种注册事件的区别

    二、事件委托

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
    6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
    7. <title>Documenttitle>
    8. head>
    9. <body>
    10. <ul>
    11. <li>第1个孩子li>
    12. <li>第2个孩子li>
    13. <li>第3个孩子li>
    14. <li>第4个孩子li>
    15. <li>第5个孩子li>
    16. <p>我不需要变色p>
    17. ul>
    18. <script>
    19. // 点击每个小li 当前li 文字变为红色
    20. // 按照事件委托的方式 委托给父级,事件写到父级身上
    21. // 1. 获得父元素
    22. const ul = document.querySelector('ul')
    23. ul.addEventListener('click', function (e) {
    24. // alert(11)
    25. // this.style.color = 'red'
    26. // console.dir(e.target) // 就是我们点击的那个对象
    27. // e.target.style.color = 'red'
    28. // 我的需求,我们只要点击li才会有效果
    29. if (e.target.tagName === 'LI') {
    30. e.target.style.color = 'red'
    31. }
    32. })
    33. script>
    34. body>
    35. html>

    上面案例,不再遍历,无法获取序号i,

    使用自定义属性

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
    6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
    7. <title>Documenttitle>
    8. head>
    9. <body>
    10. <div data-id="0">div>
    11. <script>
    12. const div = document.querySelector('div')
    13. console.log(div.dataset.id) // 0
    14. script>
    15. body>
    16. html>

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8" />
    5. <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    6. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    7. <title>tab栏切换title>
    8. <style>
    9. * {
    10. margin: 0;
    11. padding: 0;
    12. }
    13. .tab {
    14. width: 590px;
    15. height: 340px;
    16. margin: 20px;
    17. border: 1px solid #e4e4e4;
    18. }
    19. .tab-nav {
    20. width: 100%;
    21. height: 60px;
    22. line-height: 60px;
    23. display: flex;
    24. justify-content: space-between;
    25. }
    26. .tab-nav h3 {
    27. font-size: 24px;
    28. font-weight: normal;
    29. margin-left: 20px;
    30. }
    31. .tab-nav ul {
    32. list-style: none;
    33. display: flex;
    34. justify-content: flex-end;
    35. }
    36. .tab-nav ul li {
    37. margin: 0 20px;
    38. font-size: 14px;
    39. }
    40. .tab-nav ul li a {
    41. text-decoration: none;
    42. border-bottom: 2px solid transparent;
    43. color: #333;
    44. }
    45. .tab-nav ul li a.active {
    46. border-color: #e1251b;
    47. color: #e1251b;
    48. }
    49. .tab-content {
    50. padding: 0 16px;
    51. }
    52. .tab-content .item {
    53. display: none;
    54. }
    55. .tab-content .item.active {
    56. display: block;
    57. }
    58. style>
    59. head>
    60. <body>
    61. <div class="tab">
    62. <div class="tab-nav">
    63. <h3>每日特价h3>
    64. <ul>
    65. <li><a class="active" href="javascript:;" data-id="0">精选a>li>
    66. <li><a href="javascript:;" data-id="1">美食a>li>
    67. <li><a href="javascript:;" data-id="2">百货a>li>
    68. <li><a href="javascript:;" data-id="3">个护a>li>
    69. <li><a href="javascript:;" data-id="4">预告a>li>
    70. ul>
    71. div>
    72. <div class="tab-content">
    73. <div class="item active"><img src="./images/tab00.png" alt="" />div>
    74. <div class="item"><img src="./images/tab01.png" alt="" />div>
    75. <div class="item"><img src="./images/tab02.png" alt="" />div>
    76. <div class="item"><img src="./images/tab03.png" alt="" />div>
    77. <div class="item"><img src="./images/tab04.png" alt="" />div>
    78. div>
    79. div>
    80. <script>
    81. // 采取事件委托的形式 tab栏切换
    82. // 1. 获取 ul 父元素 因为 ul只有一个
    83. const ul = document.querySelector('.tab-nav ul')
    84. // 获取 5个 item
    85. const items = document.querySelectorAll('.tab-content .item')
    86. // 2. 添加事件
    87. ul.addEventListener('click', function (e) {
    88. // console.log(e.target) // e.target是我们点击的对象
    89. // 我们只有点击了 a 才会 进行 添加类和删除类操作
    90. // console.log(e.target.tagName) // e.target.tagName 点击那个对象的 标签名
    91. if (e.target.tagName === 'A') {
    92. // console.log('我选的是a')
    93. // 排他思想 ,先移除原来的active
    94. document.querySelector('.tab-nav .active').classList.remove('active')
    95. //当前元素添加 active 是 e.target
    96. // this 指向ul 不能用this
    97. e.target.classList.add('active')
    98. // 下面大盒子模块
    99. // console.log(e.target.dataset.id)
    100. const i = +e.target.dataset.id
    101. // 排他思想 ,先移除原来的active
    102. document.querySelector('.tab-content .active').classList.remove('active')
    103. // 对应的大盒子 添加 active
    104. // document.querySelector(`.tab-content .item:nth-child(${i + 1})`).classList.add('active')
    105. items[i].classList.add('active')
    106. }
    107. })
    108. script>
    109. body>
    110. html>

    三、其他事件

    3.1 页面加载事件

    注意   加载事件监听器   添加到谁身上

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
    6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
    7. <title>Documenttitle>
    8. <script>
    9. // 等待页面所有资源加载完毕,就回去执行回调函数
    10. // window.addEventListener('load', function () {
    11. // const btn = document.querySelector('button')
    12. // btn.addEventListener('click', function () {
    13. // alert(11)
    14. // })
    15. // })
    16. // img.addEventListener('load', function () {
    17. // // 等待图片加载完毕,再去执行里面的代码
    18. // })
    19. document.addEventListener('DOMContentLoaded', function () {
    20. const btn = document.querySelector('button')
    21. btn.addEventListener('click', function () {
    22. alert(11)
    23. })
    24. })
    25. script>
    26. head>
    27. <body>
    28. <button>点击button>
    29. body>
    30. html>

    3.2 页面滚动事件

    在谁的范围内滚动(滚动谁的滚动条),滚动事件加给ta

    scroll事件,一旦滚动就触发

    3.2 页面滚动事件-获取位置

    获取body元素,document.body

    获取html元素,document.documentElement

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
    6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
    7. <title>Documenttitle>
    8. <style>
    9. body {
    10. padding-top: 100px;
    11. height: 3000px;
    12. }
    13. div {
    14. display: none;
    15. margin: 100px;
    16. overflow: scroll;
    17. width: 200px;
    18. height: 200px;
    19. border: 1px solid #000;
    20. }
    21. style>
    22. head>
    23. <body>
    24. <div>
    25. 我里面有很多很多的文字
    26. 我里面有很多很多的文字
    27. 我里面有很多很多的文字
    28. 我里面有很多很多的文字
    29. 我里面有很多很多的文字
    30. 我里面有很多很多的文字
    31. 我里面有很多很多的文字
    32. 我里面有很多很多的文字
    33. 我里面有很多很多的文字
    34. 我里面有很多很多的文字
    35. 我里面有很多很多的文字
    36. 我里面有很多很多的文字
    37. 我里面有很多很多的文字
    38. 我里面有很多很多的文字
    39. div>
    40. <script>
    41. const div = document.querySelector('div')
    42. // 页面滚动事件
    43. window.addEventListener('scroll', function () {
    44. // console.log('我滚了')
    45. // 我想知道页面到底滚动了多少像素, 被卷去了多少 scrollTop
    46. // 获取html元素写法
    47. // document.documentElement
    48. // console.log(document.documentElement.scrollTop)
    49. const n = document.documentElement.scrollTop
    50. if (n >= 100) {
    51. div.style.display = 'block'
    52. } else {
    53. div.style.display = 'none'
    54. }
    55. })
    56. // const div = document.querySelector('div')
    57. // div.addEventListener('scroll', function () {
    58. // // console.log(111)
    59. // // scrollTop 被卷去的头部
    60. // console.log(div.scrollTop)
    61. // })
    62. script>
    63. body>
    64. html>

    document.documentElement.scrollTop得到是数字型 不带单位,且scrollTop可读写(写的时候不要带单位)

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
    6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
    7. <title>Documenttitle>
    8. <style>
    9. body {
    10. height: 3000px;
    11. }
    12. style>
    13. head>
    14. <body>
    15. <script>
    16. document.documentElement.scrollTop = 800
    17. window.addEventListener('scroll', function () {
    18. // 必须写到里面
    19. const n = document.documentElement.scrollTop
    20. // 得到是什么数据 数字型 不带单位
    21. // console.log(n)
    22. })
    23. script>
    24. body>
    25. html>

    还可以使用scrollTo方法,但scrollTop可读写

    3.3 页面尺寸事件

    以前用它做响应式,现在不用了

    3.3 页面尺寸事件-获取元素宽高

    包含padding(padding撑大盒子)

    四、元素尺寸与位置

    offsetWidth和offsetHeight

    offsetLeft和offsetTop

    注意:获取的是元素距离自己定位父级元素的左、上距离

    (但一般需要定位的大盒子都没有父元素,是标准流)

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
    6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
    7. <title>Documenttitle>
    8. <style>
    9. div {
    10. position: relative;
    11. width: 200px;
    12. height: 200px;
    13. background-color: pink;
    14. margin: 100px;
    15. }
    16. p {
    17. width: 100px;
    18. height: 100px;
    19. background-color: purple;
    20. margin: 50px;
    21. }
    22. style>
    23. head>
    24. <body>
    25. <div>
    26. <p>p>
    27. div>
    28. <script>
    29. const div = document.querySelector('div')
    30. const p = document.querySelector('p')
    31. // console.log(div.offsetLeft)
    32. // 检测盒子的位置 最近一级带有定位的祖先元素
    33. console.log(p.offsetLeft)
    34. script>
    35. body>
    36. html>

    getBoundClientRect针对视口,比如说滚动后,相对视口位置会改变

    五、综合案例

    关键代码:

    ①使用自定义属性+属性选择器 选出大盒子元素

    ②添加active前的判定

    1. <script>
    2. // 第一大模块,页面滑动可以显示和隐藏
    3. (function () {
    4. // 获取元素
    5. const entry = document.querySelector('.xtx_entry')
    6. const elevator = document.querySelector('.xtx-elevator')
    7. // 1. 当页面滚动大于 300像素,就显示 电梯导航
    8. // 2. 给页面添加滚动事件
    9. window.addEventListener('scroll', function () {
    10. // 被卷去的头部大于 300
    11. const n = document.documentElement.scrollTop
    12. // if (n >= 300) {
    13. // elevator.style.opacity = 1
    14. // } else {
    15. // elevator.style.opacity = 0
    16. // }
    17. // 简写
    18. elevator.style.opacity = n >= entry.offsetTop ? 1 : 0
    19. })
    20. // 点击返回页面顶部
    21. const backTop = document.querySelector('#backTop')
    22. backTop.addEventListener('click', function () {
    23. // 可读写
    24. // document.documentElement.scrollTop = 0
    25. // window.scrollTo(x, y)
    26. window.scrollTo(0, 0)
    27. })
    28. })();
    29. // 第二第三都放到另外一个执行函数里面
    30. (function () {
    31. // 2. 点击页面可以滑动
    32. const list = document.querySelector('.xtx-elevator-list')
    33. list.addEventListener('click', function (e) {
    34. // console.log(11)
    35. if (e.target.tagName === 'A' && e.target.dataset.name) {
    36. // 排他思想
    37. // 先移除原来的类active
    38. // 先获取这个active的对象
    39. const old = document.querySelector('.xtx-elevator-list .active')
    40. // console.log(old)
    41. // 判断 如果原来有active类的对象,就移除类,如果开始就没有对象,就不删除,所以不报错
    42. if (old) old.classList.remove('active')
    43. // 当前元素添加 active
    44. e.target.classList.add('active')
    45. // 获得自定义属性 new topic
    46. // console.log(e.target.dataset.name)
    47. // 根据小盒子的自定义属性值 去选择 对应的大盒子
    48. // console.log(document.querySelector(`.xtx_goods_${e.target.dataset.name}`).offsetTop)
    49. // 获得对应大盒子的 offsetTop
    50. const top = document.querySelector(`.xtx_goods_${e.target.dataset.name}`).offsetTop
    51. // 让页面滚动到对应的位置
    52. document.documentElement.scrollTop = top
    53. }
    54. })
    55. // 3. 页面滚动,可以根据大盒子选 小盒子 添加 active 类
    56. window.addEventListener('scroll', function () {
    57. // 3.1 先移除类
    58. // 先获取这个active的对象
    59. const old = document.querySelector('.xtx-elevator-list .active')
    60. // console.log(old)
    61. // 判断 如果原来有active类的对象,就移除类,如果开始就没有对象,就不删除,所以不报错
    62. if (old) old.classList.remove('active')
    63. // 3.2 判断页面当前滑动的位置,选择小盒子
    64. // 获取4个大盒子
    65. const news = document.querySelector('.xtx_goods_new')
    66. const popular = document.querySelector('.xtx_goods_popular')
    67. const brand = document.querySelector('.xtx_goods_brand')
    68. const topic = document.querySelector('.xtx_goods_topic')
    69. const n = document.documentElement.scrollTop
    70. if (n >= news.offsetTop && n < popular.offsetTop) {
    71. // 选择第一个小盒子
    72. document.querySelector('[data-name=new]').classList.add('active')
    73. } else if (n >= popular.offsetTop && n < brand.offsetTop) {
    74. document.querySelector('[data-name=popular]').classList.add('active')
    75. } else if (n >= brand.offsetTop && n < topic.offsetTop) {
    76. document.querySelector('[data-name=brand]').classList.add('active')
    77. } else if (n >= topic.offsetTop) {
    78. document.querySelector('[data-name=topic]').classList.add('active')
    79. }
    80. })
    81. })();
    82. // let n = 10
    83. // n = 20
    84. script>

  • 相关阅读:
    Leetcode 1541. Minimum Insertions to Balance a Parentheses String (括号问题好题)
    【JavaScript实现 百元买百鸡问题】
    在 Python 中使用 Pillow 进行图像处理【3/4】
    rsync+inotify-tools文件传输
    【python】爬虫系列之requests库介绍
    【无标题】
    前端开发面试题自测
    Python 有哪些好的学习资料或者博客?
    从0到一配置单节点zookeeper
    安全热点|国新办发布《携手构建网络空间命运共同体》白皮书
  • 原文地址:https://blog.csdn.net/upgrade_bro/article/details/133388247