DOM 事件模型2:阻止冒泡,popover

从popover(点击别处关闭浮层)理解冒泡与捕获

image.png

当几个DIV嵌套,触发事件时,是先进行捕获阶段的触发,再进行冒泡阶段的触发的.
例如一个popover的例子
想要的效果是点击别处关闭浮层
如图:

image.png

demo1预览效果

image.png

点击时触发了console.log函数,说明触发了document的点击事件,可是为什么没有出现浮层呢?

因为两次addEventListener是没有加参数的,所以以冒泡阶段执行两个事件,当点击点我按钮,结果是依次触发点我按钮的click事件和document的click事件.所以没有想要效果

image.png

加上debugger后发现两个函数确实都执行了,

image.png

demo2预览效果

阻止冒泡 event.stopPropagation()

Propagation翻译:传播
stopPropagation,停止传播,不要再告诉父母了,不要再往上执行冒泡事件了

image.png

demo3预览效果

image.png
3.1解决一个BUG

但是出现一个bug.当我点击点我按钮,浮层不会消失,但是当我点击浮层,浮层还是会消失,我想让浮层被点击时也不消失,只是点击其他地方消失,该如何做呢?

image.png

demo3.1预览效果

将阻止冒泡事件加在wrapper上,这样当冒泡执行到wrapper时,就不会再继续往上传播,即到wrapper就停止了

3.2 jQuery的一个BUG
image.png

$(wrapper).on("click",false);
jQuery的添加 监听事件中,如果在后面加上一个参数false,那么相当于下面的代码

$(wrapper).on("click",function(el){
   el.preventDefault();
   el.stopPropagation();
});

demo3.2预览效果

preventDefault 是另外一个相关的方法,它可以阻止事件触发后默认动作的发生。

即既阻止默认事件,又阻止冒泡事件.
但是这样会出现一个BUG.
因为给wrapper加了 el.preventDefault();组织了默认事件,所以input无法点击了,复选框无法选中,所以不要这样写

image.png

demo3.3预览效果

如何修改呢???

可以点击input

demo3.4预览效果

内存问题,如何优化

假如页面中有很多popover,那么每个document都要添加监听点击事件.这样浪费内存
解决方法:不一直监听document,只有当popover出来的时候才监听,且只监听一次,当点击完document,就清除了监听事件.这样节省内存

image.png

上面的做法就是在点击按钮的时候,才添加监听事件,并且只监听一次,节省内存

demo内存预览效果

引出bug
image.png

当点击点我这个按钮的时候,不仅触发了按钮的点击事件,而且还触发了document的事件

demo预览效果

去掉阻止冒泡事件,按理来说,点击button,只是添加了document的点击事件,而为什么又触发了document的点击事件呢?

因为代码是按照同步执行的规则来的
同步事件
即一步一步的执行,这一步没有完成,不会进行下一步.当点击了btn,会把点击事件添加到document,然后冒泡才继续往上执行.
图解:

image.png

解决方法:
让这个添加监听事件函数慢一点执行,等冒泡阶段走完再执行

image.png

在这里面的setTimeout时间设置为0,并不是立即执行,而是尽快执行。即等一会就执行,等冒泡阶段结束了在执行,在添加document的点击事件

上面的执行顺序是:先执行冒泡事件,在执行setTimeout中的内容

demo预览效果

冒泡可视化

image.png

demo代码预览

实际上是一次解析完毕

你可能感兴趣的:(DOM 事件模型2:阻止冒泡,popover)