javascript - javascript+browser 复制到剪贴板失败,数据超过 ~150k 使用 document.execCommand('copy')
问题描述
使用 document.execCommand('copy') 复制到剪贴板(a la https://stackoverflow.com/a/30810322/3160967)适用于少量数据,如果您使用调试器单步执行,也适用,但失败当数据大小达到大约 150k 时(并且您没有使用调试器单步执行)。
此外,如果以 window.getSelection() 开头的代码异步运行,它似乎可以工作。为什么?异步解决方案是稳定的,还是只是掩盖而不解决问题?
使用 Chrome 版本 66.0.3359.139
要重现此问题,请打开 DevTools 并运行以下命令:
function doclick() {
copyTest();
}
document.addEventListener('click', doclick);
function copyTest() {
var data = [];
var n = 20000; // works if n is smaller e.g. < ~6000
for(var i = 0; i < n; i++)
data[i] = String(Math.random());
var textarea = document.createElement('textarea');
textarea.value = data.join('\t')
document.body.appendChild(textarea);
var sel = window.getSelection(); // works if debugger breaks here or earlier
sel.removeAllRanges();
var r = document.createRange();
r.selectNode(textarea);
sel.addRange(r);
document.execCommand('copy');
document.body.removeChild(textarea);
alert('copied ' + textarea.value.length);
}
在 DevTools 中运行它后,我点击页面运行 doCopy(),但剪贴板没有改变。但是,如果 n < 6000 左右,它会成功。此外,如果我在上面指示的行上设置一个断点,然后在它中断后继续运行代码,它将起作用。
此外,以下似乎有效:
function copyTest() {
var data = [];
var n = 20000; // works only if n is smaller e.g. < ~6000
for(var i = 0; i < n; i++)
data[i] = String(Math.random());
var textarea = document.createElement('textarea');
textarea.value = data.join('\t')
document.body.appendChild(textarea);
function copy() {
var sel = window.getSelection(); // works if debugger breaks here or earlier
sel.removeAllRanges();
var r = document.createRange();
r.selectNode(textarea);
sel.addRange(r);
document.execCommand('copy');
document.body.removeChild(textarea);
alert('copied ' + textarea.value.length);
}
window.setTimeout(copy); // this works
}
但是,我不确定为什么这应该起作用。看起来当window.getSelection在document.body.appendChild之后立即被调用时,当被追加的孩子有足够的数据量时,window.getSelection失败,可能是因为document.body.appendChild需要另一个异步循环才能完成?无论如何,这个问题的“正确”解决方案是什么——在纯 JS 中?
解决方案
推荐阅读
- c# - NetCore 2.1 TestServer 返回 500 内部服务器错误
- image-processing - 如何使用 scipy.ndimage 找到最大的连接区域?
- java - 如何使用带有 Spring Boot 和 JavaFX 的 Maven 创建一个独立的 jar?
- java - 在 java 中使用 contains() 方法
- ios - 为什么会在没有调用 setActive: 的情况下激活自动布局约束?
- php - PHP TCPDF 在 ubuntu 14.04 上永久移动错误
- gradle - 无法为 org.gradle.api.internal.tasks.DefaultSourceSetContainer 类型的 SourceSet 容器上的参数找到方法 srcDirs()
- javascript - 如何在 JavaScript 中使用 $.getJSON 来检索 python 文件数据?
- matlab - 改变matlab中的输出顺序
- python - 使用 Pickle 在 Python 中进行套接字编程