Dom 基础操作 - 高级事件操作

89 阅读6分钟

一、 注册事件

给元素添加事件,称为 注册事件 或者 绑定事件

注册事件有两种方式: 传统方式方法监听注册方式

1.1 传统注册方式

传统注册方式:

  • 利用 on 开头的事件onclick

  • <button onclick= "alert(hi~")”>

  • btn.onclick=function(){}

  • 特点: 注册事件的 唯一性

  • 同一个元素同一个事件只能设置一个处理函数,最后注册的处理函数将会覆盖前面注册的处理函数

<html>
  <body>
    <button>传参注册事件</button>
    <button>方法监听注册事件</button>


    <script>
      var btns = document.querySelectorAll("button")

      btns[1].addEventListener(
        'click',
        function(){
          alert("hello ")
        })

      btns[1].addEventListener(
        'click',
        function(){
          alert("world!")
        })

    </script>
    
  </body>
</html>


方法监听注册方式

  • w3c标准 推荐方式
  • addEventListener()它是一个方法
  • IE9 之前的 IE 不支持此方法,可使用 attachEvent() 代替
  • 特点:同一个元素同一个事件可以注册多个监听器
  • 按注册顺序依况执行

1.2 addEventListener 事件监听方式

eventTarget .addEventListener(type,listenerl,usecapture])

eventTarget.addEventListener()方法将指定的监听器注册到eventTarget(目标对象)上,当该对象触发指定的事件时,就会执行事件处理函数。

该方法接收三个参数:

  • type: 事件类型字符串,比如click、mouseover,注意这里不要带on
  • listener: 事件处理函数,事件发生时,会调用该监听函数
  • useCapture: 可选参数,是一个布尔值,默认是false。
<html>
  <body>
    <button>传参注册事件</button>
    <button>方法监听注册事件</button>


    <script>
      var btns = document.querySelectorAll("button")

      // 事件监听方式
      btns[1].addEventListener(
        'click',
        function(){
          alert("hello ")
        })

      btns[1].addEventListener(
        'click',
        function(){
          alert("world!")
        })

    </script>
    
  </body>
</html>


1.3 attachEvent 注册事件

eventTarget.attachEvent(eventNamewithon, callback)

eventTarget.attachEvent() 方法将指定的监听器注册到eventrarget(目标对象)上,当该对象触发指定的事件时,指定的回调函数就会被执行。

该方法接收两个参数:

  • eventNameWithOn: 事件类型字符串,比如onclick、onmouseover,这里要带on

  • callback:事件处理函数,当目标触发事件时回调函数被调用

<html>
  <body>
    <button>传参注册事件</button>
    <button>方法监听注册事件</button>
    <button>attachEvent 监听事件</button>

    <script>
      var btns = document.querySelectorAll("button")
        btns[2].attachEvent('onClick',function(){
          alert("attachEvent")
        })
    </script>
    
  </body>
</html>


二、 删除事件

<html>
  <body>
    <button>添加点击事件并触发</button>
    <button>传统方式删除点击事件</button>
    <button>方法监听注册方式删除点击事件</button>

    <script>
      var btns = document.querySelectorAll("button")

      // 添加点击使劲啊
      btns[0].onclick = fn

      function fn(){
        alert('hello')
      }

      // 1. 传统方式删除事件
      btns[1].onclick = null


      // 2. 方法监听注册方式
      btns[2].removeEventListener('click',fn)

    </script>
    
  </body>
</html>


三、Dom 事件流

事件流描述的是从页面中接收事件的顺序

事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程即DOM 事件流.

比如我们给一个div注册了点击事件:

DOM 事件流分为3个阶段:

1.捕获阶段

2.当前目标阶段

3.冒泡阶段

2024-07-20_14-52-08.png

事件冒泡: IE 最早提出,事件开始时由最具体的元素接收,然后逐级向上传播到到DOM 最顶层节点的过程。

事件捕获: 网景最早提出,由DOM最顶层节点开始,然后逐级向下传播到到最具体的元素接收的过程。

注意

  1. Js 代码中只能执行 捕获 或者 冒泡 其中的一个阶段。

  2. onclick 和 attachEvent 只能得到冒泡阶段.

  3. addEventListener(type,listener[,usecapture]) 第三个参数如果是 true, 表示在事件 捕获 阶段调用事件处理程序;如果是 false(不写默认就是fa1se),表示在事件 冒泡 阶段调用事件处理程序。

  4. 实际开发中我们很少使用事件捕获,我们更关注事件冒泡.

  5. 有些事件是没有冒泡的, 比如 onblur、onfocus、onmouseenter、onmouseleave

<html>
  <body>
    <div class="father" style="width: 400px;height: 400px;background-color: yellowgreen;">
      <div class="son" style="width: 200px;height: 200px;background-color: rebeccapurple;">son</div>
    </div>

    <script>

      // dom 事件流 三个阶段
      // 1. JS 代码中只能执行捕获或者冒泡其中的一个阶段。
      // 2. onclick 和 attachEvent(ie) 只能得到冒泡阶段。

      // 3. 捕获阶段 如果addEventListener 第三个参数是 true 
      //    那么则处于捕获阶段 document->html->body ->father -> son
     var son = document.querySelector('.son')
      son.addEventListener('click',function(){
        alert('son')
      },true)

      var father = document.querySelector('.father')
      father.addEventListener('click',function(){
        alert('father')
      },true)


      // 4.冒泡阶段 如果addEventListener第三个参数是 false 或者 省略 
      //   那么则处于冒泡阶段son ->father ->body>html->document
      var son = document.querySelector('.son')
      son.addEventListener('click',function(){
        alert('son')
      })

      var father = document.querySelector('.father')
      father.addEventListener('click',function(){
        alert('father')
      },false)
    </script>
    
  </body>
</html>

四、事件对象

4.1 相关概念

  1. event 就是一个事件对象 写到我们侦听函数的 小括号里面 当形参来看

  2. 事件对象只有有了事件才会存在,它是系统给我们自动创建的,不需要我们传递参数

  3. 事件对象是我们事件的一系列相关数据的集合 跟事件相关的 比如鼠标点击里面就包含了鼠标的相关信息,鼠标坐标啊,如果是键盘事件里面就包含的键盘事件的信息 比如 判断用户按下了那个键

  4. 这个事件对象我们可以自己命名比如event、evt、e

  5. 事件对象也有兼容性问题, ie678 通过 window.event 兼容性的写法 e = e| window.event;

<html>
  <body>
   <div>btn</div>

    <script>

     var div = document.querySelector('div')
     div.addEventListener('click',(e)=>{
      // 解决兼容性问腿
      e = e || window.event
        console.log(e)
     }) 
    </script>
    
  </body>
</html>

4.2 常见属性和方法

2024-07-20_16-19-22.png

<html>
  <body>
    <div class="father">
      <a href="www.baidu.com" class='son'>link</a>
    </div>

    <script>

     var son = document.querySelector('.son')

     son.addEventListener('click',(e)=>{
      // target 返回触发事件的对象(元素)
        console.log(e.target)

        // this 返回的是绑定对事件的对象(元素)
        console.log(this)

        // 返回事件类型
        console.log(e.type)

        // 阻止默认行为: 普通浏览器 e.preventDefault();方法
        e.preventDefault();

        // 阻止默认行为:低版本浏览器ie678 returnValue 属性
        //e.returnValue;

        // 阻止默认行为:我们可以利用return false 也能阻止默认行为 没有兼容性问题
        // 但是 return 之后的代码就不执行了
        // return false;

        
     }) 
    </script>
    
  </body>
</html>

五、阻止事件冒泡

<html>
  <body>
    <div class="father" style="width: 200px;height: 200px;background-color: antiquewhite;">
      <button class='son'>btn</button>
    </div>

    <script>

     var son = document.querySelector('.son')
     son.addEventListener('click',(e)=>{
      console.log('son')
      // 1. 取消冒泡
      e.stopPropagation()

      // 2. 非标准取消冒泡
      // e.cancelable = true

      // 3. 解决兼容性问题
      if(e && e.stopPropagation){
        e.stopPropagation()
      }else{
        window.event.cancelable = true
      }
     }) 

     var father = document.querySelector('.father')
     father.addEventListener('click',(e)=>{
      console.log('father')
     }) 
    </script>
    
  </body>
</html>

六、事件委托(代理、委派)

事件委托也称为事件代理,在jQuery里面称为事件委派。

不是每个子节点单独设置事件监听器,而是事件监听器设置在其父节点上,然后利用冒泡原理影响设置每个子节点

我们只操作了一次 DOM,提高了程序的性能。

<html>
  <body>
    <ul>
      <li>1</li>
      <li>2</li>
      <li>3</li>
      <li>4</li>
    </ul>
    <script>
        var ul = document.querySelector('ul')
        ul.addEventListener('click',function(e){
          console.log('click')

          // e.target 可以获取点击的对象
          e.target.style.color = 'red'
        })
    </script>
    
  </body>
</html>

七、 常见的鼠标事件

2024-07-20_18-42-27.png

7.1 禁止右击和选中

  1. 禁止鼠标右键菜单

    contextmenu主要控制应该何时显示上下文菜单,主要用于程序员取消默认的上下文菜单

  2. 禁止鼠标选中(selectstart 开始选中)

<html>
  <body>
    <div>我是一段不愿 复制 的文字</div>

    <div>我是一段不愿 选中 的文字</div>
    <script>
        var divs = document.querySelectorAll('div')
       divs[0].addEventListener('contextmenu',function(e){
        e.preventDefault()
       })

       divs[1].addEventListener('selectstart',function(e){
        e.preventDefault()
       })
    </script>
    
  </body>
</html>

7.2 鼠标事件对象

event 对象代表事件的状态,跟事件相关的一系列信息的集合。

现阶段我们主要是用鼠标事件对象 MouseEvent 和键盘事件对象 KeyboardEvent

2024-07-20_18-54-25.png
<html>
  <body>
    <div style="
    margin-left: 2000PX;
    margin-top: 2000px;
    width: 200px;
    height: 200px;
    background-color: antiquewhite;"
    ></div>

    <script>
        var div = document.querySelector('div')
        div.addEventListener('click',function(e){

          // client 返回的永远是可视窗口的坐标
          console.log('x: ' + e.clientX)
          console.log('y: ' + e.clientY)

          // page 返回的永远是总体页面的坐标
          console.log('x: ' + e.pageX)
          console.log('y: ' + e.pageY)
        })
    </script>
    
  </body>
</html>

八、键盘事件

8.1 常用事件

事件除了使用鼠标触发,还可以使用键盘触发。

2024-07-20_19-06-58.png
<html>
  <body>

    <script>
        // 常用的键盘事件
        // 1. keyup 按键弹起时触发
        // document.onkeyup = function(){
        //   console.log('up')
        // }

        document.addEventListener("keyup",function(){
          console.log('up')
        })

        // 2. keydown 按下按键时触发
        document.addEventListener("keydown",function(){
          console.log('down')
        })

        // 3. keypress 按下按键时触发, 不能识别功能键
        document.addEventListener("keypress",function(){
          console.log('press')
        })

        // 4. 三个事件的执行顺序: keydown -> keypress -> keyup
    </script>
    
  </body>
</html>

8.2 键盘事件对象

<html>
  <body>

    <script>
        // 1. keyup 和 keydown 不区分字母大小写,A 和 a 得到的都是 65 
        document.addEventListener("keyup",function(e){
          console.log(e.keyCode)
        })

        // 2. keypress 区分字母大小写
        document.addEventListener("keypress",function(e){
          console.log(e.keyCode)
        })
    </script>
    
  </body>
</html>

8.3 ASCLL表

ASCII码 - 基本ASCII码和扩展ASCII码,中文最全ASCII码对照表0~255 (asciim.cn)