Web APIs -第2章笔记

目标:掌握事件绑定处理和事件对象,完成常见网页交互

  • 事件监听
  • 事件类型
  • 事件对象
  • 拓展知识
  • 综合案例

描述

属性/方法

效果

事件监听

元素.addEventListener()

事件监听,事件绑定,事件注册

事件类型

鼠标事件

click 鼠标点击

mouseenter 鼠标进入

mouseleave 鼠标离开

焦点事件

focus 获得焦点

blur 失去焦点

键盘事件

keydown 键盘按下

keyup 键盘抬起

文本事件 input

当表单value 被修改时触发

事件对象

e.key

判断用户按下哪个键

环境对象

this

谁调用,指向谁

事件监听

监听什么?

以前写的代码都是自动执行的,我们希望一段代码在某个特定的时机才去执行,比如

  • 点击按钮可以弹出警示框
  • 比如鼠标经过显示下拉菜单等等

像上述功能,需要浏览器时刻监听着用户的行为来做特定的事情(事件),这个就叫做监听

事件

事件是浏览器针对用户的各种行为定义出的一些列的响应机制,当程序在运行时,用户特定的行为就会触发特定的响应机制来执行指定的函数代码

  • 比如用户点击按钮时,可以 触发 click事件,弹出警示框
  • 比如用户使用鼠标划入某个盒子时,可以触发mouseenter事件,显示下拉菜单

事件监听基本用法

事件监听也称为: 事件注册、事件绑定

语法:

元素对象.addEventListener('事件类型', 事件处理函数)

事件监听三要素

  • 事件源(哪个元素对象被触发了) -> 事件监听是将事件处理函数注册到元素对象身上
  • 事件类型 (什么情况下触发,点击还是鼠标经过等)
  • 事件处理函数(要做什么事情,是弹出警告框,还是修改元素值,还是修改css属性)

<!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 class="btn">唐伯虎</button>

    <script>
      // 需求: 点击button按钮,页面会弹出一个警示框,内容显示 '秋香'
      // 事件监听语法:
      // 元素对象.addEventListener('事件类型', 事件处理函数)
      // 1. 获取元素对象 button按钮
      const btn = document.querySelector('.btn')
      // 2. 事件监听 
      btn.addEventListener('click', function () {
        alert('秋香')
      })
    </script>

  </body>

</html>

注意:

1.事件类型要加引号,小写

2.函数是点击之后再去执行,每次点击都会执行一次

事件监听-随堂练习

需求:点击关闭按钮之后,关掉登录提示盒子

分析:

①:事件源: 关闭按钮 a链接

②:事件类型:鼠标点击 click

③:事件处理程序:关闭的是父盒子

核心:利用样式的显示和隐藏完成, display:none 隐藏元素 display:block 显示元素

图片素材下载:📎images.rar

<!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>
  <style>
    .pop {
      display: block;
      visibility: visible;
      position: fixed;
      z-index: 9999;
      left: 50%;
      top: 50%;
      width: 530px;
      height: 254px;
      margin-top: -127px;
      margin-left: -265px;
      background: url(./images/login.webp) no-repeat;
    }

    .close {
      position: absolute;
      right: 0;
      top: 0;
      width: 40px;
      height: 40px;
    }
  </style>
</head>

<body>
  <div class="pop">
    <a href="javascript:;" class="close"></a>
  </div>
  <script>
    // 点击关闭按钮可以关闭父盒子
    // 确定事件三要素:
    // 1. 事件源:  a链接
    // 2. 事件类型:鼠标点击事件click
    // 3. 事件处理函数: 将div.pop盒子关闭
   
  </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>
  <style>
    .pop {
      display: block;
      visibility: visible;
      position: fixed;
      z-index: 9999;
      left: 50%;
      top: 50%;
      width: 530px;
      height: 254px;
      margin-top: -127px;
      margin-left: -265px;
      background: url(./images/login.webp) no-repeat;
    }

    .close {
      position: absolute;
      right: 0;
      top: 0;
      width: 40px;
      height: 40px;
    }
  </style>
</head>

<body>
  <div class="pop">
    <a href="javascript:;" class="close"></a>
  </div>
  <script>
    // 点击关闭按钮可以关闭父盒子
    // 确定事件三要素:
    // 1. 事件源:  a链接
    // 2. 事件类型:鼠标点击事件click
    // 3. 事件处理函数: 函数体代码为 将.pop盒子关闭

    // 获取父盒子
    const pop = document.querySelector('.pop')
    // 1. 事件源  a链接
    const closeBtn = document.querySelector('.close')
    // 2. 注册事件
    closeBtn.addEventListener('click', function () {
      // 3. 关闭父盒子  主要利用 display:none
      pop.style.display = 'none'
    })
  </script>
</body>

</html>

回调函数

回调函数:一个函数当做参数来传递给另外一个函数的时候,这个函数就是回调函数(回头调用的函数)

作用:完成某些特定任务

<script>
  // 1. 定时器间隔函数,里面第一个参数又是函数,这个匿名函数就是回调函数
  setInterval(function () {
    console.log('我是回调函数')
  }, 1000)

  // 2. addEventListener 函数的第二个参数也是函数,这个匿名函数也是回调函数
  btn.addEventListener('click', function () {
    console.log('我是回调函数')
  })
</script>

回调函数本质还是函数,只不过把它当成参数使用

使用匿名函数做为回调函数比较常见

事件监听版本(扩展阅读)

事件监听发展史:

DOM L0 :是 DOM 刚诞生的版本,使用 事件源.on事件类型 来注册事件

DOM L1:DOM级别1 于1998年10月1日成为W3C推荐标准

DOM L2:使用addEventListener注册事件

DOM L3: DOM3级事件模块在DOM2级事件的基础上重新定义了这些事件,也添加了一些新事件类型

我们常用DOM L0 和 DOM L2方式来注册事件:

  1. DOM0 事件 事件源.on事件类型 = function() { }
btn.onclick = function () {
  alert('我是弹窗1')
}
  1. DOM 2事件事件源.addEventListener(事件类型,事件处理函数)
btn.addEventListener('click', function () {
  console.log('我是回调函数')
})

区别:

on 方式同名事件会被覆盖 -> 场景:一个Dom元素身上同名事件只注册一次

addEventListener则不会 -> 场景:一个Dom元素身上同名事件要注册多次

事件类型

将众多的事件类型可分为:

  1. 鼠标事件
  2. 键盘事件
  3. 表单事件
  4. 焦点事件等

我们逐一展开学习。

事件类型的大小写敏感的字符串,统一用小写字母

鼠标事件

鼠标事件是指跟鼠标操作相关的事件,如单击、经过等。

<body>
  <div class="box"></div>

  <script>
    // 鼠标事件类型
    const box = document.querySelector('.box')
    // 1. 鼠标点击
    box.addEventListener('click', function () {
      console.log('我点击了盒子')
    })
    // 2. 鼠标进入
    box.addEventListener('mouseenter', function () {
      console.log('我鼠标经过了盒子')
    })
    // 3. 鼠标离开
    box.addEventListener('mouseleave', function () {
      console.log('我鼠标离开了盒子')
    })
  </script>

</body>
随堂练习

需求:实现轮播图点击切换功能,功能要求如下

  1. 进入页面时轮播图按照顺序自动轮播 - 使用setInterval技术
  2. 当鼠标进入轮播图时,停止自动轮播,离开轮播后,恢复自动轮播 -使用mouseenter和mouseleave事件
  3. 当点击>按钮时,轮播图顺序切换图片,点击<按钮时,轮播图倒序切换图片-使用click事件

<!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>
    <style>
        * {
            box-sizing: border-box;
        }

        .slider {
            width: 560px;
            height: 400px;
            overflow: hidden;
        }

        .slider-wrapper {
            width: 100%;
            height: 320px;
        }

        .slider-wrapper img {
            width: 100%;
            height: 100%;
            display: block;
        }

        .slider-footer {
            height: 80px;
            background-color: rgb(100, 67, 68);
            padding: 12px 12px 0 12px;
            position: relative;
        }

        .slider-footer .toggle {
            position: absolute;
            right: 0;
            top: 12px;
            display: flex;
        }

        .slider-footer .toggle button {
            margin-right: 12px;
            width: 28px;
            height: 28px;
            appearance: none;
            border: none;
            background: rgba(255, 255, 255, 0.1);
            color: #fff;
            border-radius: 4px;
            cursor: pointer;
        }

        .slider-footer .toggle button:hover {
            background: rgba(255, 255, 255, 0.2);
        }

        .slider-footer p {
            margin: 0;
            color: #fff;
            font-size: 18px;
            margin-bottom: 10px;
        }

        .slider-indicator {
            margin: 0;
            padding: 0;
            list-style: none;
            display: flex;
            align-items: center;
        }

        .slider-indicator li {
            width: 8px;
            height: 8px;
            margin: 4px;
            border-radius: 50%;
            background: #fff;
            opacity: 0.4;
            cursor: pointer;
        }

        .slider-indicator li.active {
            width: 12px;
            height: 12px;
            opacity: 1;
        }
    </style>
</head>

<body>
    <div class="slider">
        <div class="slider-wrapper">
            <img src="./images/slider01.jpg" alt="" />
        </div>
        <div class="slider-footer">
            <p>对人类来说会不会太超前了?</p>
            <ul class="slider-indicator">
                <li class="active"></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
            </ul>
            <div class="toggle">
                <button class="prev">&lt;</button>
                <button class="next">&gt;</button>
            </div>
        </div>
    </div>
    <script>
        // 初始数据对象数组
        const sliderData = [
            { url: './images/slider01.jpg', title: '对人类来说会不会太超前了?', color: 'rgb(100, 67, 68)' },
            { url: './images/slider02.jpg', title: '开启剑与雪的黑暗传说!', color: 'rgb(43, 35, 26)' },
            { url: './images/slider03.jpg', title: '真正的jo厨出现了!', color: 'rgb(36, 31, 33)' },
            { url: './images/slider04.jpg', title: '李玉刚:让世界通过B站看到东方大国文化', color: 'rgb(139, 98, 66)' },
            { url: './images/slider05.jpg', title: '快来分享你的寒假日常吧~', color: 'rgb(67, 90, 92)' },
            { url: './images/slider06.jpg', title: '哔哩哔哩小年YEAH', color: 'rgb(166, 131, 143)' },
            { url: './images/slider07.jpg', title: '一站式解决你的电脑配置问题!!!', color: 'rgb(53, 29, 25)' },
            { url: './images/slider08.jpg', title: '谁不想和小猫咪贴贴呢!', color: 'rgb(99, 72, 114)' },
        ]

        // 1. 利用随机数选取数组中的一个对象
        let index = 0

        function setSwiperData() {
            let data = sliderData[index]

            // 将data中的各种属性设置到网页的相关元素即可
            // 2. 利用选取的对象来更换图片

            // 需求:把图片元素的地址换成数据里面的图片地址
            // 2.1 获取图片元素   
            const imgBox = document.querySelector('.slider-wrapper img')

            // 2.2 把随机生成的图片地址 赋值给 图片元素.src 
            imgBox.src = data.url


            // 3. 更换文字内容
            // 3.1 获取文字盒子 p   
            const pBox = document.querySelector('.slider-footer p')

            // 3.2 把随机生成的文字赋值给 p元素.innerText  或者 innerHTML
            pBox.innerHTML = data.title


            // 4. 更换背景颜色  slider-footer 盒子
            // 4.1 获取 slider-footer 盒子    
            const divBox = document.querySelector('.slider-footer')

            // 4.2 把随机生成的背景颜色赋值给 footer元素 style
            divBox.style.backgroundColor = data.color


            // 5. 更换小圆点
            // 5.1 先选择对应的小圆点
            const liBox = document.querySelector(`.slider-indicator li:nth-child(${index + 1})`)

            // 5.2 让选出来的小圆点高亮显示
            // 将已经有小圆点样式的li标签上的class的active移除
            const activeBox = document.querySelector('.active')
            activeBox.classList.remove('active')

            liBox.classList.add('active')
        }

        let timerId = setInterval(function () {
            // 将index加1
            index++

            if (index >= sliderData.length) {
                // 将index重置回0
                index = 0
            }

            setSwiperData()

        }, 1000)


        /*
           基于昨天的综合案例,扩展如下需求
           1. 鼠标进入盒子,停止自动轮播
            -> 技术拆解
              1. 事件源:div.slider
              2. 事件类型: mouseenter
              3. 事件函数代码逻辑:clearInterval(定时器的id)
        
           2. 离开盒子,重新开启自动轮播
           ->技术拆解
              1. 事件源:div.slider
              2. 事件类型: mouseleave
              3. 事件函数代码逻辑:setInterval重新开启
        
           2. 用户点击< 和 > 自动切换图片
            技术拆解:
            1. 事件源: <  .prev   > .next
            2. 事件类型:点击事件 click
            3. 事件函数
        */

        /*
         需求1:
         1. 鼠标进入盒子,停止自动轮播
            -> 技术拆解
              1. 事件源:div.slider
              2. 事件类型: mouseenter
              3. 事件函数代码逻辑:clearInterval(定时器的id)
        */

        const silderBox = document.querySelector('.slider')

        silderBox.addEventListener('mouseenter', function () {
            // clearInterval(定时器的id)
            clearInterval(timerId)
        })

        /*
          需求2:
          2. 离开盒子,重新开启自动轮播
           ->技术拆解
              1. 事件源:div.slider
              2. 事件类型: mouseleave
              3. 事件函数代码逻辑:setInterval重新开启
        */
        silderBox.addEventListener('mouseleave', function () {

            timerId = setInterval(function () {
                // 将index加1
                index++

                if (index >= sliderData.length) {
                    // 将index重置回0
                    index = 0
                }

                setSwiperData()

            }, 1000)
        })

        /*
        需求3:
           2. 用户点击< 和 > 自动切换图片
            技术拆解:
            1. 事件源: <  .prev   > .next
            2. 事件类型:点击事件 click
            3. 事件函数
        */

        const nextBox = document.querySelector('.next')
        nextBox.addEventListener('click', function () {
            // 将index加1
            index++

            if (index >= sliderData.length) {
                // 将index重置回0
                index = 0
            }

            setSwiperData()
        })

        const prevBox = document.querySelector('.prev')
        prevBox.addEventListener('click',function(){
            // index减1
            index--
            if(index <0){
                // 如果为负数,则让图片从数组的最后一个数据开始轮播
                index = sliderData.length - 1
            }

            setSwiperData()
        })


    </script>
</body>

</html>

焦点事件

主要是针对于表单是否获得光标的事件, 获得焦点 focus 、失去焦点 blur

<!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>

    <style>
      [type=text] {
        width: 245px;
        height: 50px;
        padding-left: 20px;
        border: 1px solid #ccc;
        font-size: 17px;
        outline: none;
      }
    </style>

  </head>

  <body>
    <input type="text" class="search-text">
    <input type="text" class="search">
    <script>
      // 1. 焦点事件(手动触发)
      const search_text = document.querySelector('.search-text')
      // 1.1 获得焦点  focus
      search_text.addEventListener('focus', function () {
        console.log('获得了焦点')
      })
      // 1.2 失去焦点 blur
      search_text.addEventListener('blur', function () {
        console.log('失去了焦点')
      })
      // 2. 拓展 自动获得焦点 focus()    自动失去焦点 blur()
      //  2.1 语法: 元素.focus()  比如百度首页搜索框自动获得焦点
      const search = document.querySelector('.search')
      search.focus()
    </script>

  </body>

</html>

键盘事件和 input事件

事件

触发时机

得到表单值

keydown

按下键盘时触发

内容获取-不完整

keyup

弹起键盘时触发

输入内容-完整

input

表单value发生变化时触发

输入内容 -完整

<!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>input事件和键盘事件</title>

  <style>
    textarea {
      width: 300px;
      height: 30px;
      padding: 10px;
      border-color: transparent;
      outline: none;
      resize: none;
      background: #f5f5f5;
      border-radius: 4px;
    }
  </style>

</head>

<body>
  <textarea id="tx" placeholder="发一条友善的评论" rows="2"></textarea>

  <script>
    // 获取元素
    const tx = document.querySelector('#tx')

    // 1. 键盘事件 
    // 1.1 键盘按下事件  keydown  当我们按下键盘的时候就触发
    tx.addEventListener('keydown', function () {
      console.log('我是keydown事件' + tx.value)
    })

    // 1.2 键盘弹起事件  keyup 当我们键盘弹起的时候就触发
    tx.addEventListener('keyup', function () {
      console.log('我是keyup事件' + tx.value)
    })

    // 2. 用户输入事件 input ,是表单value的值发生变化的时候触发
    tx.addEventListener('input', function () {
      console.log('我是input事件' + tx.value)
    })
    // 3. 注意事项
    // 3.1 执行顺序  keydown →  input   →  keyup
    // 3.2 keydown 获取值的时候得不到最后一次按键的值, keyup和input可以得到用户输入内容
  </script>

</body>

</html>

注意事项

  1. 执行顺序 keydown → input → keyup
  2. keydown 获取值的时候得不到最后一次按键的值, keyup和input可以得到用户输入内容

事件对象

事件对象是什么?

注册事件中,回调函数的第一个参数就是事件对象,一般命名为event、ev、e

  • 事件对象里保存了:事件触发时的相关信息,包含属性和方法
  • 例如:鼠标点击事件中,事件对象就存了事件源的信息

使用场景

  • 可以判断用户按下哪个键,比如按下回车键可以发布新闻
  • 可以判断鼠标点击了哪个元素,从而做相应的操作
<body>
  <div class="box"></div>

  <textarea id="tx" placeholder="发一条友善的评论" rows="2"></textarea>

  <script>
    // 事件对象
    const box = document.querySelector('.box')
    box.addEventListener('click', function (e) {
      console.log(e)
      console.log(e.target) // target保存了事件源信息
    })
    const tx = document.querySelector('#tx')
    tx.addEventListener('keyup', function (e) {
      // e 就是事件对象
      // console.log(e)
      // console.log(e.key)  // a 
      // 用户如果按下的是回车键,则弹出框提示按下了回车键
      if (e.key === 'Enter') {
        alert('您按下了回车键')
      }
    })
  </script>

</body>

事件对象常见属性

事件回调函数的【第1个参数】即所谓的事件对象,通常习惯性的将这个对数命名为 eventevev

随堂练习

需求:按下回车键,可以发布评论

功能:

①:按下回车,可以显示评论信息,并且评论内容显示到对应位置

②:输入完毕,文本域清空内容

<!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>
    <style>
        .wrapper {
            width: 800px;
            display: flex;
            justify-content: flex-end;
        }

        .wrapper textarea {
            height: 50px;
            flex: 1;
            padding: 10px;
            border-radius: 4px;
            border-color: #e4e4e4;
            background: #fff;
            outline: none;
            resize: none;
        }

        .wrapper button {
            width: 70px;
            margin-left: 10px;
            border: none;
            color: #fff;
            background: #00aeec;
            border-radius: 4px;
            cursor: pointer;
        }

        .wrapper .total {
            margin-right: 80px;
            margin-top: 5px;
            color: #999;
        }

        .list {
            width: 800px;
            border: 1px solid #efce9c;
            background-color: rgb(231, 238, 191);
            padding: 10px;
        }

        .list p {
            font-size: 12px;
        }
    </style>
</head>

<body>
    <div class="wrapper">
        <textarea id="tx" placeholder="发一条友善的评论" rows="2" maxlength="200"></textarea>
        <button>发布</button>
    </div>
    <div class="wrapper">
        <span class="total">0/200字</span>
    </div>
    <div class="list">
        <p>评论信息:</p>
        <p class="msg">善语结善缘~~请发表你的评论</p>
    </div>
    <script>

        /*
           需求:
           1. 获取用户在文本域元素中的内容,并且回车表示发表动作
            -> 找事件源 id="tx"  -> 事件类型:keyup   
    
           2. 获取到文本内容之后,将这个内容更新到p元素
           ->事件函数要完成的事情
           
        */

        const textBox = document.querySelector('#tx')

        textBox.addEventListener('keyup', function (e) {
            // 判断如果用户按的是回车键,表示发表评论
            if (e.key === 'Enter') {
                //  2. 获取到文本内容之后,将这个内容更新到p元素
                document.querySelector('.msg').innerHTML = textBox.value    
                
                // 清空文本域中的内容
                textBox.value  = ''
            }

        })


    </script>
</body>

</html>

环境对象-this

环境对象:指的是函数内部特殊的 this , 它指向一个对象,调用方式不一样,this指向的对象也不一样

作用:弄清楚this的指向,可以让我们更方便编写代码

function fn() {
  console.log(this)  // this 指向哪个对象?
}
// fn()   // 直接调用函数fn(),其实相当于是 window.fn()
window.fn()

 const obj = {
  uname: '佩奇',
  sayHi: function () {
    console.log(this)  // this指向哪个对象?
  }
}
obj.sayHi()

const btn1 = document.querySelector('button')
btn1.addEventListener('click', function () {
  console.log(this)  // this指向哪个对象?
})
<body>
  <button>点击</button>

  <script>
    // 环境对象 this   粗略规则: 谁调用函数,this就指向谁

    // 1. 全局环境
    // console.log(this)  // this 指向 window 全局对象

    // 2. 普通函数
    function fn() {
      console.log(this)  // this 指向 window 全局对象
    }
    window.fn()

    // 3. 对象方法
    const obj = {
      uname: '佩奇',
      sayHi: function () {
        console.log(this)  // this 指向 obj对象
      }
    }
    obj.sayHi()

    // 4. 事件
    const btn1 = document.querySelector('button')
    btn1.addEventListener('click', function () {
      console.log(this)  // this 指向 btn 这个对象  
    })
  </script>

</body>

特点:

  • 函数的调用方式不同,this 指代的对象也不同
  • 【谁调用, this 就是谁】 是判断 this 指向的粗略规则
  • 直接调用函数,其实相当于是 window.函数,所以 this 指代 window

排他思想

是一种思路,目的是突出显示某个元素

比如,有多个元素,当鼠标点击某个元素时,只有被点击的元素会添加高亮样式,其余的元素移除样式

口诀:注意顺序

①:排除其他人

②:保留我自己

基本用法

<!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>
  <style>
    .pink {
      background-color: pink;
    }
  </style>
</head>

<body>
  <button class="pink">按钮1</button>
  <button class="pink">按钮2</button>
  <button>按钮3</button>
  <button>按钮4</button>
  <button>按钮5</button>

  <script>

    // 1. 向5个按钮注册点击事件
    const bts = document.querySelectorAll('button')
    for(let i = 0;i<bts.length;i++){
        bts[i].addEventListener('click',function(e){
            // console.log(e.target)
            // 将其他元素身上的pink类移除掉
          const pinks =   document.querySelectorAll('.pink')
          for(let j=0;j<pinks.length;j++){
            pinks[j].classList.remove('pink')
          }
            // 谁点击了就加上pink这个类到自己身上
            e.target.classList.add('pink')
        })
    }

  </script>
</body>

</html>

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值