一次element Dropdown组件clickout失效,debug过程。stopImmediatePropagation还有坑

56 阅读1分钟
  • Dropdown组件设置展开方式为click后,点击组件外部下拉菜单会自动收起。但是在我们的视图里当下拉框在拓扑图(用d3画的)内,点击拓扑图区域,下拉菜单不能正常收起,点击拓扑图外侧能正常收起。

  • 首先想到的是,拓扑图svg的click事件是否阻止冒泡,经过测试发现click能正常冒泡。查看控制台中svg元素上绑定的事件

image.png

  • 发现有mousedown事件,移除这个事件后,点击拓扑图能能正常收起。那问题就是出在这个事件身上。

  • 点击绑定这个事件,控制台打断点发现,d3中zoom函数里监听了这个事件。

  • 查看element源码发现,element的clickout事件是监听了mousedown和mouseup事件,做了一个自定义指令。这个后面发现popover里有些情况也会失效。。。elementPlus里用vueuse里的clickout函数。

  • 也就是说在d3中的某个方法阻止了冒泡。于是尝试重写mousedown.zoom事件,在新事件内去重新dispatch事件。此时下拉框能正常收起。但是页面得到拖拽功能失效。然后发现d3中绑定事件会根据namespace去区分,同一事件下,命名同一个namespace会覆盖上一个定义的事件。但是重新改掉ns后发现依旧没法解决,并且绑定的事件都不生效。最后查找源码发现,d3中写的事件里用了 stopImmediatePropagation 这个方法。这个方法不仅会阻止冒泡,并且会阻塞同名事件的监听函数执行。

  • 最后通过window.dispatchEvent 函数手动把 mousedown透传过去完成