前段时间,项目里用了 TouchEmulator 这个库,用它的原因是,这个项目是pc前端,但是有个页面跟移动端一模一样,所以引入了移动端的VantUI, 这个库的作用就是把mouse事件模拟为touch事件以此让VantUI中的touch事件能够生效。

引入后,确实也是这样,起到了该有的效果,直到……

用了富文本编辑器TinyMCE,引入这个编辑器后,问题就出来了:编辑器工具栏的内置按钮(文字大小、颜色、对齐等)统统点击了没反应,但是点击上去长按一会松开,点击事件才触发,很莫名其妙。

于是开始排查:

  1. 首先就是移除所有编辑器的自定义功能,还原到最新版本的初始状态,发现问题依旧。
  2. 会不会是编辑器的bug?考虑到这个编辑器用户量很大,如果是编辑器的bug,这么大的问题肯定不只我遇到,所以应该是我们项目其他代码有影响。
  3. 用控制台工具排查编辑器按钮的点击事件和mouse事件,逐一删除对应动作下绑定的事件,来看问题是否仍然存在,最后发现问题所在:如果删除mousedown下面的一个来自touchEmulator.js绑定的事件后,按钮的点击就恢复了正常。
  4. 查看TouchEmulator的文档和源码。

开始解决:

  1. 这个touchEmulator库一定要使用,不能不用,否则之前引用VantUI的页面有些功能无法正常使用。
  2. 要么根据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中直接引用,大功告成~

标签: vant-ui, javascript

添加新评论

0%