DOM事件
事件模型应用 点击显示浮层 点击其它地方关闭浮层
问题1 点击按钮浮层不出现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 <div id="wrapper" class="wrapper">
<button id="clickMe">点我</button>
<div id="popover" class="popover">
浮层
</div>
</div>
<script>
//点击显示浮层
clickMe.addEventListener('click', function(){
popover.style.display = 'block';
})
document.addEventListener('click', function(){
popover.style.display = 'none'
})
</script>
点击按钮的时候浮层确实出现了
但是addEventListener(‘事件’,fn,布尔值) 第三个参数不传代表false 代表冒泡
冒泡到document
document 发现事件队列里有 fn于是执行 popover.style.display = ‘none’
如何解决 ==> event.stopPropagation();
Prevents further propagation of the current event in the capturing and bubbling phases.
防止当前事件在捕获和冒泡阶段的进一步传播。
早一点的前端肯定会认为还有一个方法阻止冒泡 event.cancelBubble = true ;不好意思 该属性已废弃
1 | //点击显示浮层 |
问题2 虽然解决了阻止冒泡 但是当你点击浮层时 浮层也会消失
这样就不能在按钮上阻止冒泡 因为点击浮层也会冒泡到wrapper
- 因为btn会冒泡到 wrapper
- popover会冒泡到 wrapper
- 所以在它们的父节点做阻止冒泡
1 | <div id="wrapper" class="wrapper"> |
问题3 现在点击按钮浮层出现 点击浮层浮层浮层不消失 但是有性能问题
- 100个浮层就是100个事件队列 10000个呢?
现在我们先换jq来实现刚刚的效果
jq提供了一个非常方便的方法 $(node).on(‘click’,false) 第二个参数代表 阻止默认事件 和阻止传播
又偶生出一个bug 就是.on(‘事件’,false) 你在checkbox外的任何一层 阻止默认事件 这个checkbox就无法选中
1 | <div id="wrapper" class="wrapper"> |
所以我们还是单独阻止传播
1 | $(clickMe).on('click',function(){ |
解决问题3 性能问题
- 点击按钮的时候显示浮层 同时添加一个document监听
- 为什么监听不会触发 因为 wrapper哪里阻止了 冒泡
1
2
3
4
5
6
7
8
9
10
11
12
13
14$(clickMe).on('click',function(){
$(popover).show();
//只有显示的时候监听一次 但是不会触发 因为 wrapper上阻止了冒泡
//这样我只监听一次 click 同时马上干掉这个监听事件
$(document).one('click',function(){
console.log('doc')
$(popover).hide();
})
});
//所以只能这样写 单独阻止它的冒泡 不阻止默认事件
$(wrapper).on('click',function(e){
e.stopPropagation(); //阻止冒泡
});
问题4 如果不在wrapper上不阻止冒泡 点击btn为什么浮层不显示
1 | $(clickMe).on('click',function(){ |
- 在你点击btn的时候它会做两件事
- 1 浮层显示出来
- 2 document的事件队列里 添加一个函数
- 3 事件开始冒泡
- 4 开始发现 document的事件队列里有一个函数
- 5 执行 document事件队列里的函数
- 6 浮层隐藏了