前段时间,项目里用了 TouchEmulator 这个库,用它的原因是,这个项目是pc前端,但是有个页面跟移动端一模一样,所以引入了移动端的VantUI
, 这个库的作用就是把mouse事件模拟为touch事件以此让VantUI中的touch事件能够生效。
引入后,确实也是这样,起到了该有的效果,直到……
用了富文本编辑器TinyMCE
,引入这个编辑器后,问题就出来了:编辑器工具栏的内置按钮(文字大小、颜色、对齐等)统统点击了没反应,但是点击上去长按一会松开,点击事件才触发,很莫名其妙。
于是开始排查:
- 首先就是移除所有编辑器的自定义功能,还原到最新版本的初始状态,发现问题依旧。
- 会不会是编辑器的bug?考虑到这个编辑器用户量很大,如果是编辑器的bug,这么大的问题肯定不只我遇到,所以应该是我们项目其他代码有影响。
- 用控制台工具排查编辑器按钮的点击事件和mouse事件,逐一删除对应动作下绑定的事件,来看问题是否仍然存在,最后发现问题所在:如果删除
mousedown
下面的一个来自touchEmulator.js
绑定的事件后,按钮的点击就恢复了正常。 - 查看TouchEmulator的文档和源码。
开始解决:
- 这个
touchEmulator
库一定要使用,不能不用,否则之前引用VantUI
的页面有些功能无法正常使用。 - 要么根据
touchEmulator
文档,在编辑器标签上加上data-no-touch-simulate
来使其对此元素及子元素无效,要么修改touchEmulator
的源码,自定义其生效条件,前者很好实现,下面来看下修改源码如何实现:
好在touchEmulator
的源码很少,就一个文件,其实主要改动的地方就是在createTouchList
方法中:
/**
* create a touchList based on the mouse event
* @param mouseEv
* @returns {TouchList}
*/
function createTouchList(mouseEv) {
var touchList = TouchList();
// 对鼠标事件模拟touch事件进行白名单过滤,只允许特定页面执行,否则会影响其他组件的点击事件,比如tinymce。
if (mouseEv.target.baseURI.indexOf('xxx/xxx') > -1) {
touchList.push(new Touch(eventTarget, 1, mouseEv, 0, 0));
}
return touchList;
}
如果是修改源码,记得移除掉package.json
中的对原touchEmulator
库的依赖,改为使用修改过后的touchEmulator
文件,并在main.js
中直接引用,大功告成~