事件冒泡、事件捕获、取消冒泡、取消默认事件

 

事件冒泡:

只要结构上,非视觉上嵌套关系的元素,或存在事件冒泡的功能,即同一事件,自子元素冒泡到父元素。

如:当点击子元素content时,会向上依次执行(自底向上冒泡)

<div class="wrapper">
    <div class="box">
        <div class="content"></div>
    </div>
</div>
<script>
let wra = document.getElementsByClassName('wrapper')[0]
let box = document.getElementsByClassName('box')[0]
let content = document.getElementsByClassName('content')[0]
wra.addEventListener('click', function() {
    console.log('wrapper')
}, false)
box.addEventListener('click', function() {
    console.log('box')
}, false)
content.addEventListener('click', function() {
    console.log('content')
}, false)
</script>

 

事件捕获:

跟事件冒泡正好相反,结构上嵌套关系的元素,存在事件捕获,当点击子元素content时,执行顺序是自父元素到子元素, 开启捕获,ele.addEventListener('type', Fn, true) 参数三改为 true即可开启捕获功能(自顶向下)

wra.addEventListener('click', function() {
    console.log('wrapper')
}, true)
box.addEventListener('click', function() {
    console.log('box')
}, true)
content.addEventListener('click', function() {
    console.log('content')
}, true)

 

如果同时定义事件捕获和事件冒泡,执行顺序为:

永远是:先捕获后冒泡,不管执行顺序如何颠倒,但是事件传递到点击的子元素时,此时是事件执行,因为点击的就是子元素本身,所以,下边当点击content子元素时,先捕获是没问题的,到了content时,遵循的是事件的执行顺序,也就是哪一个事件先绑定的,哪一个先执行,冒泡事件先绑定,先输出  'content - 冒泡' ,之后 输出  'content - 捕获' ,然后接着向上冒泡 。。。

let wra = document.getElementsByClassName('wrapper')[0]
let box = document.getElementsByClassName('box')[0]
let content = document.getElementsByClassName('content')[0]
wra.addEventListener('click', function() {
    console.log('wrapper')
}, false)
box.addEventListener('click', function() {
    console.log('box')
}, false)
content.addEventListener('click', function() {
    console.log('content')
}, false)
wra.addEventListener('click', function() {
    console.log('wrapper')
}, true)
box.addEventListener('click', function() {
    console.log('box')
}, true)
content.addEventListener('click', function() {
    console.log('content')
}, true)

 

取消事件冒泡:

event.stopPropagation( ) IE9及以下不支持

IE: event.cancelBubble = true

content.addEventListener('click', function(e) {
    console.log('content - 冒泡')
    e.stopPropagation()
}, false)

封装 取消冒泡/捕获方法:

// 需要传一个事件对象
function cancelBubble(e) {
    if (e.cancelBubble) {
        e.cancelBubble = true
    }else {
        // e.stopPropagation()
        e.stopPropagation()
    }
}

实际开发:

取消冒泡在实际开发非常常用,只不过一些框架都帮你封装好了,这一点你需要理解。

 

取消默认事件:

3种方式:

1、return false ( 注意: 只有句柄的方式 dom.onclick   绑定的事件才好使,addEventListener 不好使!!!)

2、e.preventDefault( ) IE9 及以下不兼容

3、e.returnValue = false  IE兼容

封装 阻止默认事件方法:

function cancelHandler(e) {
    if (e.preventDefault) {
        e.preventDefault()  
    } else {
        e.returnValue = false
    }
}

补充:只有cancelable 属性设置为true时,才可以使用 preventDefault()来取消其默认行为。

 

扩展:

一、取消a标签的默认事件:

方法1:

a.onclick = function() {
    return false
}

方法2:

括号里边false 或0 都行

<a href="javascript:void(false)">click</a>

 

二、兼容事件对象

在老版本ie浏览器,没有事件对象e,但是 存在window.event.

所以,原生开发中会这样写:

dom.onclick = function (e) {
   let e = e || window.event
}

 

三、事件源 - 事件对象上有一个属性,专门记录事件源的

所为的事件源,就是点击的哪一个元素,事件源就是谁。。。

(1)event.target  火狐只有这个

(2)event.srcElement  IE只有这个

谷歌两个都有。

封装兼容方法:

function handleTarget(e) {
    let event = e || window.event
    if (event.target) {
        return event.target
    } else {
        return event.srcElement
    }
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值