【踩坑】【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);
})();
}
解决方案
调用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
会监听全局document
的focusin
事件导致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:chrome
中Ancestors
勾选上,可以看到某个元素的事件会触发document
的那些绑定事件。通过这个也能发现问题所在