事件捕获的具体实践
场景:有一系列的下拉列表组件,交互规则为:
1、点击dropdown的title,列表展开
2、选中(点击)option,列表自动收起。
3、点击其他的dropdown,在新的dropdown列表展开的同时前一个收起。
4、点击空白处,展开的dropdown收起
按照经典思路是这么处理的:
1、组件的title添加click时切换的逻辑
2、给document添加一个click事件,将所有展开的列表收起,通过事件冒泡触发
3、点击dropdown的title的click事件中,除去组件内已有逻辑,再加上停止冒泡到document的代码
4、完成上一步之后,会发现无法实现第三个需求,因为document上的handler被停掉了,于是在title的click事件中,还要添加一段和document的click事件中相同的代码,把其他的展开列表收起
感觉有一些冗余,而且组件内部和外部的耦合太严重
如果用事件捕获的思路是这样的:
1、组件的title添加click时切换的逻辑
2、在事件捕获阶段给document添加click事件,将所有展开的列表收起,需要加个判断e.target为title时则不执行,否则点title会很快地收起又展开
这样就可以了,顺序上会先执行document的click事件收起上一个列表,再执行下一个列表title的click事件展开新列表,无缝衔接。
还有一个交互需求是这样的,点开面板之后,在面板上是多选项,于是不能点击一下就自动收起,这里只要把上面第二步的屏蔽区域从title扩大到整个面板即可。