事件对象和事件冒泡、捕获机制

冒泡与捕获

事件冒泡与捕获是事件处理的两种机制,主要描述当在一个元素上有两个相同类型的事件处理器被激活会发生什么。

再点击子元素时,浏览器运行了两种不同的阶段:捕获阶段和冒泡阶段。捕获阶段的行为:

  • 浏览器检查元素的最外层祖先<html>,是否在捕获阶段中注册了一个onclick事件处理程序,如果是,则运行它;
  • 然后,它移动到<html>中单击元素的下一个祖先元素,并执行相同的操作,然后是单击元素再下一个祖先元素,依此类推,直到到达实际点击的元素;

而冒泡与捕获恰恰相反:

  • 浏览器检查实际点击的元素是否在冒泡阶段中注册了一个onclick事件处理程序,如果是,则运行它;
  • 然后它移动到下一个直接的祖先元素,并做同样的事情,然后是下一个,等等,直到它到达<html>元素;

而现代浏览器在默认情况下,所有事件处理程序都在冒泡阶段进行注册。因此上面代码在点击子元素时会先执行子元素绑定的事件,然后向上冒泡,触发父元素绑定的事件。

addEventListener 函数的第三个参数是个布尔值。含义:

  • 当布尔值是 false 时(这也是默认值),表示向上冒泡触发事件;
  • 当布尔值是 true 时,表示向下捕获触发事件;

不能冒泡的事件

有些事件是不会冒泡的。比如:

  • blur 元素失去焦点时触发,focusout 事件也是失去焦点时触发,但可以冒泡;
  • focus 元素获取焦点时触发;
  • mouseenter 鼠标移动到元素上时会触发该事件,与之对应的是 mouseover 事件,但会冒泡;
  • mouseleave 鼠标离开元素时触发,与之对应的是 mouseout,但会冒泡;

事件冒泡可以让我们利用事件委托,尤其是处理大量子元素时,如果给每个子元素都绑定事件,这是不优雅的,可以将事件绑定到父元素上,并让子节点上发生的事件冒泡到父节点上,利用 e.target 属性可以获取到当前触发事件的子元素。

事件对象中的方法

  • stopPropagation() 阻止事件冒泡,当设置后,点击该元素时父元素绑定的事件就不会再触发;
  • preventDefault() 阻止默认事件的发生;
  • stopImmediatePropagation() 它用来阻止监听同一事件的其他事件监听器被调用以及阻止事件冒泡,比如给同一个 div 元素绑定多个 click 事件(使用 addEventListener 方法可以注册多个),当在第二个事件函数中调用 stopImmediatePropagation 方法时,点击 div 元素时,后面注册的 click 将不会被触发,而且还会阻止事件冒泡;

在 IE 浏览器中,使用 e.cancelBubble = true 也可以取消事件冒泡;使用 e.returnValue = false 也能阻止默认事件的发生。

target 与 currentTarget 有什么不同?

target 属性指向的是事件目标,而 currentTarget 属性指向的是正在处理当前事件的对象,它总是指向事件绑定的元素。而 target 指向的可能不是定义时的事件目标。

例如:

div.addEventListener('click', (e) => {
    console.log(e.target, e.currentTarget);
},false);

e.target 可能指向 div 元素,也可能指向它的子元素。而 e.currentTarget 总是指向 div 元素。

例题

下面代码,当输入框有焦点时,打印顺序是怎样的?

const ipt = document.querySelector('input');
ipt.addEventListener('click', () => {
  console.log('click');
},false);

ipt.addEventListener('focus', () => {
  console.log('focus');
}, false);

ipt.addEventListener('mousedown', () => {
  console.log('mousedown');
}, false);

ipt.addEventListener('mouseenter', () => {
  console.log('mouseenter');
}, false);

结果:

mouseenter  // 鼠标移动到元素上时触发
mousedown   // 鼠标按下时触发
focus       // 输入框有焦点时触发
click       // 点击事件最后触发
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值