JavaScript的事件机制

JavaScript和HTML之间的交互是通过事件实现的。事件,就是文档或浏览器窗口中发生的一些特定的交互瞬间。点击按钮这件事,就被称作事件,而响应某个事件的函数通常被称为事件处理程序

1.接下来先说下DOM事件

DOM事件级别
DOM有4次版本更新,与DOM版本变更,产生了3种不同的DOM事件:DOM 0级事件处理DOM 2级事件处理DOM 3级事件处理。由于DOM 1级中没有事件的相关内容,所以没有DOM 1级事件。
DOM 0级事件
1.on-event (HTML 属性):

<button onclick="alert('xxx')">Click</button>

on-event (非HTML 属性):
像是window或document此类没有实体元素的情况:

window.onload = function(){
  document.write("Hello world!");
};

若是实体元素:

<button id="btn">Click</button>

var btn = document.getElementById('btn');
 btn.onclick = function(){
     alert(this.id);//这个this 指向当前元素
 }

解除绑定

btn.onclick = null

2.同一个元素的同一种事件只能绑定一个函数,否则后面的函数会覆盖之前的函数
3.不存在兼容性问题

DOM 2级事件
1.Dom 2级事件是通过 addEventListener 绑定的事件
2.同一个元素的同种事件可以绑定多个函数,按照绑定顺序执行
3.解绑Dom 2级事件时,使用 removeEventListener

btn.addEventListener("click", function () {
    console.log("btn")
}, false);
btn.addEventListener("click", function () {
    console.log("btn1");
}, false);

解绑

btn.removeEventListener( "click" ,函数名,事件流阶段)

Dom 2级事件有三个参数:第一个参数是事件名(如click);第二个参数是事件处理程序函数;第三个参数如果是true的话表示在捕获阶段调用,为false的话表示在冒泡阶段调用

注意:
1.removeEventListener():不能移除匿名添加的函数。
2.IE9之下的浏览器不支持DOM2级事件处理程序

IE事件处理程序
IE9之前的浏览器实现了DOM中类似的两个方法 attachEvent和detachEvent。由于IE9之前的版本只支持事件冒泡,所以它只有两个参数
1.同一个元素的同种事件可以绑定多个函数,但是执行顺序不是按照添加他们的顺序执行,而是相反的顺序触发
2.解绑事件时,使用 detachEvent

btn.attachEvent("onclick", function () {
  //console.log(this===window);//这个this指向window的
  console.log("btn")
})
btn.attachEvent("onclick", function () {
  console.log("btn1")
})

执行结果是 btn1,btn
解绑

btn.detachEvent( "onclick" ,函数名)

DOM 3级事件

  • UI事件,当用户与页面上的元素交互时触发,如:load、scroll 焦点事件,当元素获得或失去焦点时触发,如:blur、focus
  • 鼠标事件,当用户通过鼠标在页面执行操作时触发如:dblclick、mouseup
  • 滚轮事件,当使用鼠标滚轮或类似设备时触发,如:mousewheel 文本事件,当在文档中输入文本时触发,如:textInput
  • 键盘事件,当用户通过键盘在页面上执行操作时触发,如:keydown、keypress
  • 合成事件,当为IME(输入法编辑器)输入字符时触发,如:compositionstart
  • 变动事件,当底层DOM结构发生变化时触发,如:DOMsubtreeModified 同时DOM3级事件也允许使用者自定义一些事件。

DOM事件流
事件流指的就是网页元素接收事件的顺序。事件流可以分成两种机制:

  • 事件捕获(Event Capturing)(会从document开始触发,一级一级往下传递,依次触发,直到真正事件目标为止)
    -在这里插入图片描述

  • 事件冒泡(Event Bubbling)(从当前触发的事件目标一级一级往上传递,依次触发,直到document为止)
    -在这里插入图片描述

当一个事件发生后,会在子元素和父元素之间传播(propagation)。这种传播分成三个阶段:
1.捕获阶段:事件从window对象自上而下向目标节点传播的阶段;
2.目标阶段:真正的目标节点正在处理事件的阶段;
3.冒泡阶段:事件从目标节点自下而上向window对象传播的阶段
在这里插入图片描述

注意:
1.尽管“DOM2级事件”规范要求事件应该从document对象开始传播,但是IE9,Safari,Chrome,Opera和Firefox这些浏览器都是从window对象开始捕获事件的
2.IE8以及更早版本的浏览器不支持捕获阶段,而且只冒泡到document

我们可以通过addEventListener()方法来绑定click事件:
假设HTML 如下:

<div class="parent">
    <div class="child"></div>
  </div>

JavaScript 代码如下:

var parent = document.querySelector(".parent");
var child = document.querySelector(".child");

parent.addEventListener("click", function () {
    console.log("捕获:parent");
  }, true);
  parent.addEventListener("click", function () {
    console.log("冒泡:parent");
  }, false);
  child.addEventListener("click", function () {
    console.log("捕获:child");
  }, true);
  child.addEventListener("click", function () {
    console.log("冒泡:child");
  }, false);

捕获:parent
捕获:child
冒泡:child
冒泡:parent

而如果直接点击「父元素」,则出现:

捕获:parent
冒泡:parent

那么,子层中的捕获或冒泡谁先谁后呢?要看你代码的顺序而定:谁在前就先执行谁

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值