【踩坑】【viewerjs】使用viewerjs之后,无法使用js执行文本复制

162 阅读1分钟

【踩坑】【viewerjs】使用viewerjs之后,无法使用js执行文本复制

现象

使用viewerjs之后,无法再使用js文本复制 文本复制代码

export function copyClip(content: string) {
  const input = document.createElement('input');
  return (function () {
    document.body.appendChild(input);
    input.setAttribute('value', content);
    input.select();
    document.execCommand('copy');
    document.body.removeChild(input);
  })();
}

image.png

解决方案

调用viewerjs内部的清除focus事件监听

  share() {
    if (!this.viewer) return;
    (this.viewer as any).clearEnforceFocus(); // 调用viewerjs内部的清除focus事件监听
    copyClip(this.imgUrl as string);
    setTimeout(() => {
      this.$message.success('已复制链接到剪切板,去分享吧~');
      (this.viewer as any).enforceFocus(); 
    }, 100);
  }

排查链路

1、判断复制过程那一步出了问题,调试可知,input.select() 方法未起作用 2、猜测不起作用原因,把viewerjs销毁之后,可复制成功 3、分析源码中销毁做了那些步骤,那些步骤是核心的问题所在 4、定位到clearEnforceFocus方法为关键 看enforceFocus函数实现可得到结论:viewerjs会监听全局documentfocusin事件导致select事件失效

    enforceFocus: function enforceFocus() {
      var _this = this;
      this.clearEnforceFocus();
      // EVENT_FOCUSIN ->focusin事件
      addListener(document, EVENT_FOCUSIN, this.onFocusin = function (event) {
        var viewer = _this.viewer;
        var target = event.target;
        if (target === document || target === viewer || viewer.contains(target)) {
          return;
        }
        while (target) {
          // Avoid conflicts with other modals (#474, #540)
          if (target.getAttribute('tabindex') !== null || target.getAttribute('aria-modal') === 'true') {
            return;
          }
          target = target.parentElement;
        }
        viewer.focus();
      });
    },

ps:chromeAncestors勾选上,可以看到某个元素的事件会触发document的那些绑定事件。通过这个也能发现问题所在

image.png