20230331----重返学习-event事件对象

day-039-thirty-nine-20230331-event事件对象

event事件对象

事件句柄

  1. 鼠标事件

    1. click左键单击事件

      const box = document.getElementById("box");
      box.onclick = function () {
        console.log("click左键单击事件");
      };
      
    2. dblclick左键双击事件

      const box = document.getElementById("box");
      box.ondblclick = function () {
        console.log("dblclick左键双击事件");
      };
      
    3. mouseover有冒泡移入事件 mouseout有冒泡移出事件

      const box = document.getElementById("box");
      box.onmouseover = function () {
        console.log("mouseover有冒泡移入事件");
      };
      box.onmouseout = function () {
        console.log("mouseout有冒泡移出事件");
      };
      
    4. mouseenter没冒泡移入事件 mouseleave没冒泡移出事件

      const box = document.getElementById("box");
      box.onmouseenter = function () {
        console.log("mouseenter没冒泡移入事件");
      };
      box.onmouseleave = function () {
        console.log("mouseleave没冒泡移出事件");
      };
      
    5. mousemove移动事件,反复触发

      const box = document.getElementById("box");
      box.onmousemove = function () {
        console.log("mousemove移动事件");
      };
      
    6. mousedown移入按下事件 mouseup移入抬起事件

      const box = document.getElementById("box");
      box.onmousedown = function () {
        console.log("mousedown移入按下事件");
      };
      box.onmouseup = function () {
        console.log("mouseup移入抬起事件");
      };
      
    7. contextmenu右键单击事件,默认出现菜单栏

      const box = document.getElementById("box");
      box.oncontextmenu = function () {
        console.log("contextmenu右键单击");
      };
      
  2. 键盘事件

    1. 事件类型

      1. keydown键盘按下事件

        const inputText = document.getElementById('inputText')
        inputText.onkeydown = function(){
          console.log('keydown键盘按下事件',inputText.value)
        }
        
      2. keyup键盘抬起事件

        const inputText = document.getElementById('inputText')
        inputText.onkeyup = function(){
          console.log('keyup键盘抬起事件',inputText.value)
        }
        
      3. keypress键盘按下抬起事件

        • 特殊的键如Control键/Ctrl键、Alt键、Shift键、Esc键,不是适用于该事件
          • 监听一个用户是否按下按键请使用 onkeydown 事件,所有浏览器都支持 onkeydown 事件
        const inputText = document.getElementById('inputText')
        inputText.onkeypress = function(){
          console.log('keypress键盘按下抬起事件',inputText.value)
        }
        
    2. 事件触发主体

      1. input元素 textarea元素
      2. window全局窗口
      3. document.documentElement
      4. document.body
  3. 表单事件

    1. input值修改事件,内容发生改变就会触发

      const inputText = document.getElementById('inputText')
      inputText.oninput = function(){
        console.log('input值修改事件',inputText.value)
      }
      
    2. change值改变事件,内容发生改变并且失去焦点

      const inputText = document.getElementById('inputText')
      inputText.onchange = function(){
        console.log('change值改变事件',inputText.value)
      }
      
    3. focus获取焦点事件,blur失去焦点事件

      const inputText = document.getElementById('inputText')
      inputText.onfocus = function(){
        console.log('focus获取焦点事件',inputText.value)
      }
      inputText.onblur = function(){
        console.log('blur失去焦点事件',inputText.value)
      }
      
  4. 系统事件

    1. scroll监听滚动事件

      window.onscroll = function () {
        console.log("scroll监听滚动事件");
      };
      
    2. resize监听视口改变事件,监控页面大小改变就会触发

      window.onresize = function () {
        let theHTML = document.documentElement || document.body;
        console.log("resize监听视口改变事件", theHTML.clientHeight);
      };
      
    3. load监听页面渲染事件,页面上所有页面相关的内容加载完毕后最后执行js,如图片及压缩文件等内容都加载出来后

      window.onload = function () {
        console.log("load监听页面渲染事件");
      };
      
    4. DOMContentLoaded监听DOM渲染事件,页面上所有页面内容加载完毕后最后执行js,相关的内容如图片及压缩文件等内容不用加载出来

      • 支持DOM2的使用,不支持DOM0级的使用
      // DOM0---不支持DOMContentLoaded监听DOM渲染事件
      document.onDOMContentLoaded = function () {
        console.log("DOMContentLoaded监听DOM渲染事件-不支持DOM0级事件");
      };
      // DOM2---支持DOMContentLoaded监听DOM渲染事件
      document.addEventListener("DOMContentLoaded", function () {
        console.log("DOMContentLoaded监听DOM渲染事件-支持DOM2级事件");
      });
      
  5. 移动端事件

    1. 事件类型

      1. touchstart手指按下事件

        • click在移动端有300ms的延迟,所以用touchstart事件
          let box = document.getElementById("box");
          box.ontouchstart = function () {
            console.log("touchstart手指按下事件");
          };
        
      2. touchmove手指移动事件,手指得保持按下的状态并移动才会触发

          let box = document.getElementById("box");
          box.ontouchmove = function () {
            console.log("touchmove手指移动事件");
          };
        
      3. touchend手指抬起事件

          let box = document.getElementById("box");
          box.ontouchend = function () {
            console.log("touchend手指抬起事件");
          };
        
    2. 移动端事件流速事项

      1. 只能在移动端触发,在PC端不会触发相关的事件

每个事件都会自带一个event事件对象

事件默认行为

  • 取消事件的默认行为----e.preventDefault()
    • 事件绑定函数的那个函数,会自带形参,第一个形参一般为e,是event事件对象的简写
    • 浏览器兼容性
      • e.preventDefault() ,FF浏览器,除了IE浏览器之外的其它浏览器
        • FF表示除了IE浏览器之外的其它浏览器
      • e.returnValue=false ,IE浏览器去除默认器默认行为
    • 常见默认行为
      1. 右键单击----事件默认行为—出现菜单栏

        <!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 id="box">aaaa</div>
          </body>
        </html>
        <script>
          let box = document.getElementById("box");
          box.oncontextmenu = function (e) { //会自带形参--e: event事件对象
            console.log("oncontextmenu", e);
            e.preventDefault(); //取消事件默认行为
          };
        </script>
        
      2. a标签----事件默认行为----跳转页面

事件定义

事件定义,就是指事件绑定的方式

  1. DOM0级事件

    1. 表现方式

      1. html与JavaScript代码相混合,不推荐使用

        • 实际上就是 行内标签属性的方式

          <div onclick="console.log('hahaha')">元素divdiv>
          
          <div onclick="show(10,20)">111div>
          <script>
          function show(n,m){
              console.log("111",n,m);
          }
          script>
          
      2. html与JavaScript代码相分离,推荐使用

        • 实际上就是 DOM元素中js的方式

          <div id="box">111div>
          <script>
          box.onclick=function(e){
              console.log("111",e);
          }
          script>
          
        • 移除事件

          <div id="box">111div>
          <script>
          box.onclick=null
          script>
          
    2. 原理: 是给元素对象的私有属性赋值

    • 每一个事件就是DOM元素对象上的一个属性,就是给DOM元素对象上的属性赋值
    • 特色
      • 如果同一个事件句柄,绑定多次,后面会把前面的给覆盖

      • 如果元素没有某个事件的私有属性,就不能基于这个方法绑定0级事件

        // DOM0---不支持DOMContentLoaded监听DOM渲染事件
        document.onDOMContentLoaded = function () {
          console.log("DOMContentLoaded监听DOM渲染事件-不支持DOM0级事件");
        };
        // DOM2---支持DOMContentLoaded监听DOM渲染事件
        document.addEventListener("DOMContentLoaded", function () {
          console.log("DOMContentLoaded监听DOM渲染事件-支持DOM2级事件");
        });
        
      • 事件默认触发阶段必定是冒泡阶段

  2. DOM2级事件—推荐

    1. 语法:

      1. 添加事件对应方法: ele.addEventListener(事件句柄,回调函数,事件执行方向) ,FF浏览器-除IE外浏览器
        • 事件执行方向
          • 事件执行方向: false 冒泡阶段,默认
          • 事件执行方向: true 捕获阶段
        • IE浏览器兼容-添加方法: ele.attachEvent(on+事件句柄,回调函数);
          • 不能设置事件执行方向,只能冒泡阶段
          • IE浏览器在2023年基本上已经被淘汰了,不必兼容
      2. 移除事件方法: ele.removeEventListener(事件句柄,回调函数,事件执行方向) ,FF浏览器-除IE外浏览器
        • 事件执行方向
          • 事件执行方向: false 冒泡阶段,默认
          • 事件执行方向: true 捕获阶段
        • 移除事件方法时,回调函数必须是同一个堆/引用地址
        • IE浏览器兼容-移除方法: ele.detachEvent(on+事件句柄,回调函数);
          • IE浏览器在2023年基本上已经被淘汰了,不必兼容
      <div id="box">111div>
      <script>
      box.addEventListener("click",function(e){
        console.log("111")
      })
      box.addEventListener("click",function(e){
        console.log("222")
      })
      const show = function show(){
      console.log("333")
      }
      box.addEventListener("click",show)
      box.removeEventListener("click",show)
      script>
      
    2. 原理: 采用的是发布订阅模式----基于事件池实现的-添加方法/放方法,执行方法,移除方法

      • 如果同一个事件句柄,绑定多次,全部都会执行
        [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3VNIUO0C-1680273292510)(./事件池大体思路.png)]

总结

基于浏览器事件池机制来完成的,通过addEventListener往事件池中增加方法,removeEventListener从中移除方法

  1. 只要浏览器中有这个事件,都可以通过2级事件来绑定,DOMContentLoaded(jquery中的ready事件就是监听这个事件实现的)
  2. 同一个事件可以绑定多个方法,触发顺序,先绑定的先触发
  3. 可以人为规定在捕获或冒泡阶段触发,默认是在冒泡阶段
  4. DOM2级事件如果不兼容IE的话需要省去on
    • 2023年基本上都要省去on,因为IE浏览器目前已经基本上淘汰过时了

事件周期

  1. 捕获阶段: 沿着DOM树向下传播,由外向内
    • IE浏览器没有捕获阶段
  2. 目标触发: 监听事件触发
  3. 冒泡阶段: 沿着DOM向上传播,由内向外
DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>取消事件的默认行为title>
    <style>
      #divBox {
        height: 500px;
        width: 500px;
        background-color: red;
      }
      #pBox {
        height: 300px;
        width: 300px;
        background-color: pink;
      }
      #spanBox {
        display: block;
        height: 100px;
        width: 100px;
        background-color: greenyellow;
      }
    style>
  head>
  <body>
    <div id="divBox">
      <p id="pBox">
        <span id="spanBox">点击这里触发click点击事件span>
      p>
    div>
  body>
html>
<script>
  let divBox = document.getElementById("divBox");
  let pBox = document.getElementById("pBox");
  let spanBox = document.getElementById("spanBox");
  divBox.onclick = function () {
    console.log("DOM0级冒泡-divBox");
  };
  pBox.onclick = function () {
    console.log("DOM0级冒泡-pBox");
  };
  spanBox.onclick = function () {
    console.log("DOM0级冒泡-spanBox");
  };


  divBox.addEventListener('click', function () {
    console.log("DOM2级-不写默认-冒泡-divBox");
  });
  pBox.addEventListener('click', function () {
    console.log("DOM2级-不写默认-冒泡-pBox");
  });
  spanBox.addEventListener('click', function () {
    console.log("DOM2级-不写默认-冒泡-spanBox");
  });

  divBox.addEventListener('click', function () {
    console.log("DOM2级-写true捕获-divBox");
  },true);
  pBox.addEventListener('click', function () {
    console.log("DOM2级-写true捕获-pBox");
  },true);
  spanBox.addEventListener('click', function () {
    console.log("DOM2级-写true捕获-spanBox");
  },true);
//DOM2级-写true捕获-divBox
//DOM2级-写true捕获-pBox
//DOM2级-写true捕获-spanBox

//DOM0级冒泡-spanBox
//DOM2级-不写默认-冒泡-spanBox

//DOM0级冒泡-pBox
//DOM2级-不写默认-冒泡-pBox

//DOM0级冒泡-divBox
//DOM2级-不写默认-冒泡-divBox
script>

阻止事件冒泡

  • e.stopPropagation() , FF浏览器-除IE浏览器外的其它浏览器
    • IE浏览器兼容: e.cancelBubble=true
DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>取消事件的默认行为title>
    <style>
      #divBox {
        height: 500px;
        width: 500px;
        background-color: red;
      }
      #pBox {
        height: 300px;
        width: 300px;
        background-color: pink;
      }
      #spanBox {
        display: block;
        height: 100px;
        width: 100px;
        background-color: greenyellow;
      }
    style>
  head>
  <body>
    <div id="divBox">
      <p id="pBox">
        <span id="spanBox">点击这里触发click点击事件span>
      p>
    div>
  body>
html>
<script>
  let divBox = document.getElementById("divBox");
  let pBox = document.getElementById("pBox");
  let spanBox = document.getElementById("spanBox");
  divBox.onclick = function () {
    console.log("DOM0级冒泡-divBox");
  };
  pBox.onclick = function () {
    console.log("DOM0级冒泡-pBox");
  };
  spanBox.onclick = function () {
    console.log("DOM0级冒泡-spanBox");
  };


  //方向:冒泡方向 由里向外
  divBox.addEventListener('click', function () {
    console.log("DOM2级-不写默认-冒泡-divBox");
  });
  pBox.addEventListener('click', function () {
    console.log("DOM2级-不写默认-冒泡-pBox");
  });
  spanBox.addEventListener('click', function () {
    console.log("DOM2级-不写默认-冒泡-spanBox");
  });

  //方向:捕获方向 由外向里
  divBox.addEventListener('click', function () {
    console.log("DOM2级-写true捕获-divBox");
  },true);
  pBox.addEventListener('click', function (e) {
    e.stopPropagation()//阻止事件冒泡,也阻止事件捕获。//e是形参,表示事件对象。
    console.log("DOM2级-写true捕获-pBox");
  },true);
  spanBox.addEventListener('click', function () {
    console.log("DOM2级-写true捕获-spanBox");
  },true);



//DOM2级-写true捕获-divBox
//DOM2级-写true捕获-pBox //后续不会再触发事件,因为在这个元素的捕获阶段上调用了e.stopPropagation()。
script>

目标对象

  • e.target目标对象:事件源,是触发事件的元素(可变的);FF
    • 在一个函数被绑定到一个事件后,当该事件被触发时,它始终指向事件被触发的源头。
      • 源头就是当前元素或者当前元素的后代元素。
      • 事件委托主要就是使用这个属性。
    • IE浏览器兼容: event.srcElement
  • this—>绑定事件的元素,如果ES5写法,this就不变
    • 在一个函数被绑定到一个事件属性后,一般ES5中this就指向该事件属性所在的元素对象。
    • 在一个函数被绑定到一个事件属性后,一般ES6箭头函数中this就指向定义当前函数时当前作用域的this对象。
  <body>
    <span id="box">boxspan>
  body>
<script>
  let box = document.getElementById("box");
  //目标对象:事件源,是触发事件的元素(可变的)----放大镜
  //this---》绑定事件的元素,如果ES5写法,this就不变
  box.onclick = function (e) {
    console.log("box:-->this:", this); //box
    console.log("box:-->e.target:", e.target); //目标对象,自身box
  };
  document.body.onclick = function (e) {
    console.log("body:-->this:", this); //box
    console.log("body:-->e.target:", e.target); //目标对象,后代元素box,也可能是自身body。
  };
script>
  <body>
    <span id="box">boxspan>
  body>
<script>
  let box = document.getElementById("box");
  box.onclick = (e) => {
    console.log("box:-->this:", this); //window
    console.log("box:-->e.target:", e.target); //目标对象,自身box
  };
  document.body.onclick = (e) => {
    console.log("body:-->this:", this); //window
    console.log("body:-->e.target:", e.target); //目标对象,后代元素box,也可能是自身body。
  };
script>

按键编码

在按键相关的事件中,作为形参e传入回调函数的event事件对象中,e.keyCode表示键盘按键的按键编码。
这些编码一般不用记,写这事件后,直接按一下,测一下。

DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>键码编码title>
  head>
  <body>
    <input type="text" id="theInput" />
  body>
html>
<script>
  let theInput = document.getElementById("theInput");
  //e.keyCode 键盘按键的按键编码
  theInput.onkeydown = function (e) {
    console.log("e.keyCode", e.keyCode);
  };
script>

div移动走

<style>
  #box {
    width: 100px;
    height: 100px;
    background-color: skyblue;
    position: absolute;
  }
style>
<body>
<div id="box">div>
body>
<script>
window.onkeydown = function (e) {
  let step = 10; //每次移动走 10px
  let box = document.getElementById("box");
  box.style.position = "absolute";
  // let style = window.getComputedStyle(box);
  let style = box.getBoundingClientRect();
  let theTop = parseInt(style.top) || 0;
  let thisTop = theTop;
  let theLeft = parseInt(style.left) || 0;
  let thisLeft = theLeft;
  //console.log(e.keyCode);
  //上38 下40 左37 右39
  switch (e.keyCode) {
    case 38:
      thisTop = theTop - step;
      console.log(theTop);
      box.style.top = `${thisTop}px`;
      break;
    case 40:
      thisTop = theTop + step;
      box.style.top = `${thisTop}px`;
      break;
    case 37:
      thisLeft = theLeft - step;
      box.style.left = `${thisLeft}px`;
      break;
    case 39:
      thisLeft = theLeft + step;
      box.style.left = `${thisLeft}px`;
      break;

    default:
      break;
  }
};
script>

坐标

  • event事件对象的常用坐标属性
    • offsetX/offsetY: 鼠标距离目标元素e.target的左侧/顶部距离
    • clientX/clientY: 鼠标距离视口的左侧/顶部距离
      • x/y: 鼠标距离视口的左侧/顶部距离
    • pageX/pageY: 鼠标距离整个文档document的左侧/顶部距离
    • screenX/screenY: 鼠标距离电脑屏幕的左侧/顶部距离
DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>坐标title>
    <style>
      body {
        height: 2000px;
      }
      #box {
        width: 100px;
        height: 100px;
        background-color: skyblue;
        position: fixed;
        top: 100px;
        left: 200px;
      }
    style>
  head>
  <body>
    <div id="box">div>
  body>
html>
<script>
  let box = document.getElementById("box");
  box.onclick = function handleClick(e) {
    console.log(`e.offsetX:`, e.offsetX, ` ;e.offsetY:`, e.offsetY);

    console.log(`e.clientX:`, e.clientX, ` ;e.clientY:`, e.clientY);
    console.log(`e.x:`, e.x, ` ;e.y:`, e.y);

    console.log(`e.pageX:`, e.pageX, ` ;e.pageY:`, e.pageY);

    console.log(`e.screenX:`, e.screenX, ` ;e.screenY:`, e.screenY);
  };

  //e.offsetX: 49  ;e.offsetY: 48
  //e.clientX: 249  ;e.clientY: 148
  //e.x: 249  ;e.y: 148
  //e.pageX: 249  ;e.pageY: 640
  //e.screenX: 257  ;e.screenY: 247
script>

进阶参考

  1. 视频预习网址 – 有效期一年
  2. CSS属性-filter

你可能感兴趣的:(重返学习,学习,javascript,前端)