BOM #第二天

目录

一、事件绑定的方式

二、事件解除

三、event对象

四、事件响应链

五、事件代理

六、停止冒泡


一、事件绑定的方式

1.句柄式写法 :只能绑定一个事件处理函数

<style>
  .box {
    width: 200px;
    height: 200px;
    background-color: green;
  }
  .active {
    background-color: red;
  }
</style>

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

 <script>
    let box = document.querySelector('.box');
    // 1.句柄式写法 只能绑定一个事件处理函数
    document.querySelector('.box').onclick = changeBack
    function changeBack() {
      box.classList.contains('active') ? box.classList.remove('active') : box.classList.add('active');
    }
  </script>

2.addEventListener: 可以绑定多个事件处理函数

<style>
  .box {
    width: 200px;
    height: 200px;
    background-color: green;
  }
  .active {
    background-color: red;
  }
</style>

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

<script>
    // 2.addEventListener 可以绑定多个事件处理函数
    let box = document.querySelector('.box');
    function changeBack() {
      box.classList.contains('active') ? box.classList.remove('active') : box.classList.add('active');
    }
    function changeContent() {
      box.innerHTML ? box.innerHTML = '' : box.innerHTML = '新增内容';
    }
    box.addEventListener('click', changeBack);
    box.addEventListener('click', changeContent);
  </script>

二、事件解除

1.句柄式的事件解除:element.onclick = false;

  <style>
    .yhq {
      width: 300px;
      height: 100px;
      border-radius: 24px;
      background-color: coral;
      color: #FFF;
      text-align: center;
      line-height: 100px;
    }
  </style>

<div class="yhq">大额优惠券</div>

<script>
    let yhq = document.querySelector('.yhq');
    
    function getyhq() {
      alert("领取成功");
      yhq.style.opacity = 0.5;

      // 解除绑定事件
      yhq.onclick = false;
    }
    yhq.onclick = getyhq;  // 赋值函数不加小括号
</script>

2.事件监听器的解除方式 :element.removeEventListener('事件类型', 事件处理函数);

  <style>
    .yhq {
      width: 300px;
      height: 100px;
      border-radius: 24px;
      background-color: coral;
      color: #FFF;
      text-align: center;
      line-height: 100px;
    }
  </style>

<div class="yhq">大额优惠券</div>

<script>
    let yhq = document.querySelector('.yhq');
    
    function getyhq() {
      alert("领取成功");
      yhq.style.opacity = 0.5;

      // 解除绑定事件
      yhq.removeEventListener('click', getyhq);
    }
    yhq.addEventListener('click', getyhq); // 函数不加小括号
</script>

三、event对象

event对象:盒子被触发时的事件, 如鼠标移动事件、键盘按下事件

鼠标even事件常用属性:

属性           含义

clientX

盒子触发时离左边的距离(可视区域)

clientY

盒子触发时离顶部的距离(可视区域)

offsetX

盒子触发时离盒子左边的距离

offsetY

盒子触发时离盒子顶部的距离

 pageX

盒子触发时离界面左边的距离

pageY

盒子触发时离界面顶部的距离

screenX

盒子触发时离屏幕左边的距离

screenY

盒子触发时离屏幕顶部的距离

对以上even事件属性的解释:

鼠标点击红圈中绿点的地方

 css:
 

  <style>
    div {
      width: 200px;
      height: 200px;
      background-color: pink;
      margin: 100px;
    }
  </style>

 html:

<div></div>

js:

   <script>
     let div = document.querySelector("div");
     div.onclick = function(e) {
       console.log(e);
       /* 
        clientX: 185
        clientY: 120
        offsetX: 78
        offsetY: 21
        screenX: 234
        screenY: 224
        */     
     }
   </script>

【案例】盒子上下左右移动

 <style>
    .box {
      width: 300px;
      height: 300px;
      border-radius: 24px;
      background-color: coral;
      color: #FFF;
      text-align: center;
      line-height: 100px;
      position: relative;
    }
  </style>

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

<script>
    let box = document.querySelector('.box');
    window.addEventListener('keydown', function(event) {
      // console.log(event);
      if (event.key == 'ArrowUp') {
        box.style.top = parseFloat(getComputedStyle(box).top) - 3 + 'px';
      }
      if (event.key == 'ArrowDown') {
        box.style.top = parseFloat(getComputedStyle(box).top) + 3 + 'px';
      }
      if (event.key == 'ArrowLeft') {
        box.style.left = parseFloat(getComputedStyle(box).left) - 3 + 'px';
      }
      if (event.key == 'ArrowRight') {
        box.style.left = parseFloat(getComputedStyle(box).left) + 3 + 'px';
      }
      
    })
  </script>

四、事件响应链

1.事件冒泡:标签之间形成嵌套关系之后,绑定同一事件,会由子级逐渐冒泡到父级

<style>
    .outer {
      width: 300px;
      height: 300px;
      background-color: purple;
      position: relative;
    }
    .middle {
      width: 200px;
      height: 200px;
      background-color: red;
      position: absolute;
      left: 360px;
    }
    .inner {
      width: 100px;
      height: 100px;
      background-color: green;
      position: absolute;
      left: 360px;
    }
  </style>

  <div class="outer">
    <div class="middle">
      <div class="inner"></div>
    </div>
  </div>

  <script>
    let outer = document.querySelector('.outer');
    let middle = document.querySelector('.middle');
    let inner = document.querySelector('.inner');

    function handleOuter() {
      console.log('outer');
    }
    function handleMiddle() {
      console.log('middle');
    }
    function handleInner() {
      console.log('inner');
    }
    // 按照事件冒泡响应过程来触发
    outer.onclick = handleOuter;
    middle.onclick = handleMiddle;
    inner.onclick = handleInner;
  </script>

2.事件捕获:标签之间形成嵌套关系之后,绑定同一事件,会由父级逐渐冒泡到子级

  • 格式:node.addEventListener('事件类型', 处理函数, true); 
  • 只有addEventListener绑定的事件才有事件捕获
<style>
    .outer {
      width: 300px;
      height: 300px;
      background-color: purple;
      position: relative;
    }
    .middle {
      width: 200px;
      height: 200px;
      background-color: red;
      position: absolute;
      left: 360px;
    }
    .inner {
      width: 100px;
      height: 100px;
      background-color: green;
      position: absolute;
      left: 360px;
    }
  </style>

  <div class="outer">
    <div class="middle">
      <div class="inner"></div>
    </div>
  </div>

  <script>
    let outer = document.querySelector('.outer');
    let middle = document.querySelector('.middle');
    let inner = document.querySelector('.inner');

    function handleOuter() {
      console.log('outer');
    }
    function handleMiddle() {
      console.log('middle');
    }
    function handleInner() {
      console.log('inner');
    }
    // 按照事件捕获响应过程来触发
    outer.addEventListener('click', handleOuter, true);
    middle.addEventListener('click', handleMiddle, true);
    inner.addEventListener('click', handleInner, true);
  </script>

3.如果既有事件冒泡也有事件捕获,就会先捕获再冒泡!!

<style>
    .outer {
      width: 300px;
      height: 300px;
      background-color: purple;
      position: relative;
    }
    .middle {
      width: 200px;
      height: 200px;
      background-color: red;
      position: absolute;
      left: 360px;
    }
    .inner {
      width: 100px;
      height: 100px;
      background-color: green;
      position: absolute;
      left: 360px;
    }
  </style>

  <div class="outer">
    <div class="middle">
      <div class="inner"></div>
    </div>
  </div>

  <script>
    let outer = document.querySelector('.outer');
    let middle = document.querySelector('.middle');
    let inner = document.querySelector('.inner');

    function handleOuter() {
      console.log('outer');
    }
    function handleMiddle() {
      console.log('middle');
    }
    function handleInner() {
      console.log('inner');
    }

    // 按照事件冒泡响应过程来触发
    outer.onclick = handleOuter;
    middle.onclick = handleMiddle;
    inner.onclick = handleInner;

    // 按照事件捕获响应过程来触发
    outer.addEventListener('click', handleOuter, true);
    middle.addEventListener('click', handleMiddle, true);
    inner.addEventListener('click', handleInner, true);
  </script>

五、事件代理

事件代理:借助事件冒泡处理过程,并且通过事件源对象获取事件目标,将事件绑定到父节点身上

【案例】通过给ul绑定事件,点击某个li时,该li的样式改变

  <ul>
    <li>列表标签1</li>
    <li>列表标签2</li>
    <li>列表标签3</li>
    <li>列表标签4</li>
    <li>列表标签5</li>
  </ul>

  <script>
    let ul = document.querySelector("ul");
    let lis = document.querySelectorAll('li');
    
    // 新增一个字节点
    let li = document.createElement("li");
    li.innerHTML = '列表标签6';
    ul.append(li);
    
    // 给ul绑定
    ul.addEventListener('click', function(event) {
    // 排他思想 点击li之前去掉其他li的样式
      for (let i = 0; i < lis.length; i++) {
        lis[i].style.color = '';
        lis[i].style.fontSize = '';
      }
      event.target.style.color = 'red';
      event.target.style.fontSize = '24px';
      // console.log(event.target);   
    })
  </script>

结果:

六、停止冒泡

1.停止冒泡:点击子级之后,父级不再被触发

2.停止冒泡的方式:

  • event.stopPropagation();
  • event.cancelBubble = true

兼容性比较好的一种写法:

event.stopPropagation ? event.stopPropagation() : event.cancelBubble = true;

  <style>
    .outer {
      width: 300px;
      height: 300px;
      background-color: purple;
      position: relative;
    }

    .middle {
      width: 200px;
      height: 200px;
      background-color: red;
      position: absolute;
      left: 360px;
    }

    .inner {
      width: 100px;
      height: 100px;
      background-color: green;
      position: absolute;
      left: 360px;
    }

    .box {
      width: 140px;
      height: 220px;
      background-color: lightsalmon;
      display: none;
      position: absolute;
    }
  </style>

  <div class="outer">
    <div class="middle">
      <div class="inner"></div>
    </div>
  </div>

<script>
 let outer = document.querySelector('.outer');
    let inner = document.querySelector('.inner');

    function handleOuter() {
      console.log('outer');
    }

    function handleInner() {
      console.log('inner');

      // event.stopPropagation();
      // 兼容性比较好的一种写法
      event.stopPropagation ? event.stopPropagation() : event.cancelBubble = true;
    }

    outer.onclick = handleOuter;
    inner.onclick = handleInner;
  </script>

3.阻止默认事件

【案例】点击鼠标右键,弹出自己写的盒子

 <style>
    .box {
      width: 140px;
      height: 220px;
      background-color: lightsalmon;
      display: none;
      position: absolute;
    }
  </style>

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

window.oncontextmenu = function (event) {
      document.querySelector(".box").style.display = "block"

      document.querySelector(".box").style.top = event.pageY + "px";
      document.querySelector(".box").style.left = event.pageX + "px";

      return false;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值