Dom事件冒泡——可视化编辑器实战
一、概况
最近公司开发一款类似bootstrap可视化编辑器的web项目,方便以后快速迭代开发。但在开发过程中遇到了事件冒泡的棘手问题,下面具体介绍。
二、编辑器设计思路
(图片截自bootstrap)
如图所示:
1、拖动按钮绑定拖动事件,当然mousemove、mouseup事件要绑到body上
2、目标盒子对象也注册mousemove和up事件,当鼠标移动到盒子上,它们抛出事件(designer-xxx)
3、操作对象监听到designer-xxx事件,做出对应操作
三、问题
1、目标盒子会有很多,且嵌套,显而易见要使用阻止冒泡
2、在拖动已添加的盒子时,鼠标被本盒子(移动的盒子)遮挡,移动过程中没办法触发兄弟节点的mouse事件........
四、解决问题
1、阻止冒泡必须要,方法有:
event.stopPropagation(); // 或者 return false;
看着好像ok了哈,试一下,结果拖拽绑定在body上的mousemove事件也杯具了,怎么办?
1>. 将body上的mousemove事件改成捕获的就ok了,Jquery.on不支持修改,那就自己写一个:
if(el.addEventListener) { el.addEventListener('mousemove', function(){}, true); } else { alert('用高级浏览器吧,兄弟!'); }
2>. 通过event.target判断
// 得判断target同是box才阻止冒泡 $('.panel-box').on('mousemove', function(event) { if($(event.target).hasClass('.box') && event.target != this) { return; } // TODO 处理逻辑... });
2、遮挡问题how to do?
1>. 最简单,移动的时候,将盒子向下偏移,将鼠标暴露出来(完全可以接受的效果,也最方便,因为项目的重头戏完全不在这里)
2>. 完全重构一下思路:
1)目标盒子不再注册mouse事件,将发送designer-xxx的功能转移到拖拽的对应事件中去
2)需要维护一个结构,遍历dom树,将目标盒子标注出z-index的层级关系,类似
{ uniqKey:{ box: $('xxx'), z-index: 0 }, uniqKey:{ box: $('xxx'), z-index: 1 } ....... }
3)拖拽过程中,结合鼠标位置和上述结构就能得出唯一的盒子(冒泡也没用了,就body注册了事件),处理即可
但是为了这么个功能也太不值了......
3>. 兄弟结点被我挡了,那就由我来通知你们!!!
一句话,拖拽盒子move的时候,兄弟结点自己trigger一个事件出去(trigger也是冒泡的哦),然后兄弟节点自己监听即可。
五、总结
1、以上针对冒泡的处理,个人认为能覆盖绝大多数问题了,遇到灵活处理即可
2、项目进行只是初期,思路还要经受考验,仅供参考
3、代码块手工书写,金融项目,考不出来,有问题请百度