如何将文本复制到剪贴板(多浏览器)?
相关:How does Trello access the user’s clipboard?
huntsbot.com – 高效赚钱,自由工作
概述
有三个主要的浏览器 API 用于复制到剪贴板:
异步剪贴板 API [navigator.clipboard.writeText] Chrome 66 中提供的以文本为中心的部分(2018 年 3 月)访问是异步的并使用 JavaScript 承诺,可以编写以便安全用户提示(如果显示)不会中断页面中的 JavaScript .文本可以直接从变量复制到剪贴板。仅在通过 HTTPS 提供的页面上受支持。在 Chrome 66 页面中,非活动标签可以在没有权限提示的情况下写入剪贴板。 document.execCommand(‘copy’)(已弃用) 大多数浏览器从 2015 年 4 月起支持此功能(请参阅下面的浏览器支持)。访问是同步的,即停止页面中的 JavaScript 直到完成,包括显示和用户与任何安全提示进行交互。文本从 DOM 中读取并放置在剪贴板上。在测试期间 ~ 2015 年 4 月,只有 Internet Explorer 被记录为在写入剪贴板时显示权限提示。覆盖复制事件 请参阅关于覆盖复制事件的剪贴板 API 文档。允许您从任何复制事件修改剪贴板上显示的内容,可以包括纯文本以外的其他格式的数据。这里没有涉及,因为它没有直接回答这个问题。
一般开发说明
当您在控制台中测试代码时,不要期望剪贴板相关命令能够正常工作。通常,页面需要处于活动状态(异步剪贴板 API)或需要用户交互(例如用户点击)以允许 (document.execCommand(‘copy’)) 访问剪贴板,详情请参见下文。
重要(此处注明 2020/02/20)
请注意,由于这篇文章最初是由 deprecation of permissions in cross-origin IFRAMEs 和其他 IFRAME “sandboxing” 编写的,因此嵌入的演示“运行代码片段”按钮和“codepen.io 示例”无法在某些浏览器(包括 Chrome 和 Microsoft Edge)中运行。
要开发创建您自己的网页,请通过 HTTPS 连接提供该页面以进行测试和开发。
这是一个演示代码工作的测试/演示页面:https://deanmarktaylor.github.io/clipboard-test/
异步+后备
由于浏览器对新 Async Clipboard API 的支持级别较高,您可能希望回退到 document.execCommand(‘copy’) 方法以获得良好的浏览器覆盖率。
这是一个简单的示例(可能无法嵌入此站点,请阅读上面的“重要”说明):
函数 fallbackCopyTextToClipboard(text) { var textArea = document.createElement(“textarea”); textArea.value = 文本; // 避免滚动到底部 textArea.style.top = “0”; textArea.style.left = “0”; textArea.style.position = “固定”; document.body.appendChild(textArea); textArea.focus(); textArea.select();尝试 { var 成功 = document.execCommand(‘copy’); var msg = 成功? ‘成功’ : ‘不成功’; console.log(‘Fallback: 复制文本命令是’ + msg); } catch (err) { console.error(‘Fallback: 糟糕,无法复制’, err); } document.body.removeChild(textArea); } 函数 copyTextToClipboard(text) { if (!navigator.clipboard) { fallbackCopyTextToClipboard(text);返回; } navigator.clipboard.writeText(text).then(function() { console.log(‘Async: 复制到剪贴板成功!’); }, function(err) { console.error(‘Async: 无法复制文本: ‘, 呃); }); } var copyBobBtn = document.querySelector(’.js-copy-bob-btn’), copyJaneBtn = document.querySelector(‘.js-copy-jane-btn’); copyBobBtn.addEventListener(‘click’, function(event) { copyTextToClipboard(‘Bob’); }); copyJaneBtn.addEventListener(‘click’, function(event) { copyTextToClipboard(‘Jane’); }); 设置剪贴板为BOB < button class=“js-copy-jane-btn”>将剪贴板设置为 JANE 尝试粘贴到此处查看剪贴板上的内容:
(codepen.io 示例可能不起作用,请阅读上面的“重要”注释)请注意,此代码段在 Stack Overflow 的嵌入式预览中效果不佳,您可以在此处尝试:https://codepen.io/DeanMarkTaylor/pen/RMRaJX?editors=1011
异步剪贴板 API
MDN 参考
Chrome 66 公告帖(2018 年 3 月)
参考 Async Clipboard API 草稿文档
请注意,通过 Chrome 66 中的权限 API,可以“请求权限”并测试对剪贴板的访问权限。
var text = "Example text to appear on clipboard";
navigator.clipboard.writeText(text).then(function() {
console.log('Async: Copying to clipboard was successful!');
}, function(err) {
console.error('Async: Could not copy text: ', err);
});
document.execCommand(‘复制’)
本文的其余部分将介绍 document.execCommand(‘copy’) API 的细微差别和细节。
浏览器支持
JavaScript document.execCommand(‘copy’) 支持已增加,请参阅以下链接了解浏览器更新: (deprecated)
Internet Explorer 10+(尽管本文档表明 Internet Explorer 5.5+ 提供了一些支持)。
Google Chrome 43+(~2015 年 4 月)
Mozilla Firefox 41+(2015 年 9 月发货)
Opera 29+(基于 Chromium 42,~2015 年 4 月)
简单示例
(可能无法嵌入本网站,请阅读上面的“重要”说明)
var copyTextareaBtn = document.querySelector(‘.js-textareacopybtn’); copyTextareaBtn.addEventListener(‘click’, function(event) { var copyTextarea = document.querySelector(‘.js-copytextarea’); copyTextarea.focus(); copyTextarea.select(); try { var success = document.execCommand(’ copy’); var msg =successful ? ‘successful’ : ‘unsuccessful’; console.log(‘复制文本命令是’ + msg); } catch (err) { console.log(‘糟糕,无法复制’); } }); 复制文本区域 你好我是一些文本 < /p>
复杂示例:复制到剪贴板而不显示输入
如果屏幕上可以看到 textarea 或 input 元素,上述简单示例非常有效。
在某些情况下,您可能希望将文本复制到剪贴板而不显示 input / textarea 元素。这是解决此问题的方法的一个示例(基本上是插入元素,复制到剪贴板,删除元素):
使用 Google Chrome 44、Firefox 42.0a1 和 Internet Explorer 11.0.8600.17814 进行测试。
(可能无法嵌入本网站,请阅读上面的“重要”说明)
函数 copyTextToClipboard(text) { var textArea = document.createElement(“textarea”); // // *** 此样式是一个额外的步骤,可能不需要。 *** // // 为什么会在这里?确保: // 1. 元素能够具有焦点和选择。 // 2. 如果元素是 Flash 渲染,它的视觉影响最小。 // 3. 如果 textarea 元素不可见,则可能发生的选择和复制的片状更少。 // // 可能元素甚至不会渲染,甚至不会出现 // 闪光,所以其中一些只是预防措施。然而,在 // Internet Explorer 中,该元素是可见的,而弹出框 // 询问用户是否允许网页 // 复制到剪贴板。 // // 无论滚动位置如何,都放置在屏幕的左上角。 textArea.style.position = ‘固定’; textArea.style.top = 0; textArea.style.left = 0; // 确保它具有较小的宽度和高度。设置为 1px / 1em // 不起作用,因为这在某些浏览器上会产生负 w/h。 textArea.style.width = ‘2em’; textArea.style.height = ‘2em’; // 我们不需要填充,如果它进行 Flash 渲染,则减小大小。 textArea.style.padding = 0; // 清理所有边框。 textArea.style.border = ‘无’; textArea.style.outline = ‘无’; textArea.style.boxShadow = ‘无’; // 如果出于任何原因渲染,请避免白框闪烁。 textArea.style.background = ‘透明’; textArea.value = 文本; document.body.appendChild(textArea); textArea.focus(); textArea.select();尝试 { var 成功 = document.execCommand(‘copy’); var msg = 成功? ‘成功’ : ‘不成功’; console.log(‘复制文本命令是’ + msg); } catch (err) { console.log(‘糟糕,无法复制’); } document.body.removeChild(textArea); } var copyBobBtn = document.querySelector(‘.js-copy-bob-btn’), copyJaneBtn = document.querySelector(‘.js-copy-jane-btn’); copyBobBtn.addEventListener(‘click’, function(event) { copyTextToClipboard(‘Bob’); }); copyJaneBtn.addEventListener(‘click’, function(event) { copyTextToClipboard(‘Jane’); }); 设置剪贴板为BOB < button class=“js-copy-jane-btn”>将剪贴板设置为 JANE 尝试粘贴到此处查看剪贴板上的内容:
补充说明
仅当用户采取行动时才有效
所有 document.execCommand(‘copy’) 调用都必须是用户操作的直接结果,例如点击事件处理程序。这是一种防止在用户不期望的情况下弄乱用户剪贴板的措施。
有关详细信息,请参阅 Google Developers post here。
剪贴板 API
请注意,可在此处找到完整的剪贴板 API 草案规范:https://w3c.github.io/clipboard-apis/
是否支持?
如果命令“浏览器支持”,则 document.queryCommandSupported(‘copy’) 应该返回 true。
如果现在调用 document.execCommand(‘copy’) 将成功,则 document.queryCommandEnabled(‘copy’) 返回 true。检查以确保从用户启动的线程调用命令并满足其他要求。
但是,作为浏览器兼容性问题的一个示例,Google Chrome 从 2015 年 4 月到 10 月仅在从用户启动的线程调用命令时才从 document.queryCommandSupported(‘copy’) 返回 true。
请注意下面的兼容性详细信息。
浏览器兼容性详情
虽然对 document.execCommand(‘copy’) 的简单调用包含在作为用户点击的结果而调用的 try/catch 块中,但可以让您获得最大的兼容性,但使用以下有一些附加条件:
对 document.execCommand、document.queryCommandSupported 或 document.queryCommandEnabled 的任何调用都应包含在 try/catch 块中。
不同的浏览器实现和浏览器版本在调用而不是返回 false 时会引发不同类型的异常。
不同的浏览器实现仍在不断变化,Clipboard API 仍处于草稿阶段,因此请记住进行测试。
很抱歉破坏聚会,但是document.execCommand is obsolete。请参阅developer.mozilla.org/en-US/docs/Web/API/Document/execCommand
@tnkh 当然,但替代品(剪贴板 API)尚未完全烘焙和支持。
目前全球 91% 的用户都支持剪贴板 API:caniuse.com/mdn-api_clipboard_writetext
我只是在回退后添加了焦点的重置:var previousFocusElement = document.activeElement (....all the fallback code...) previousFocusElement.focus();
这是一个很好的、彻底的答案 - 简而言之,使用标题 Async + Fallback 下此答案中描述的方法 - 这实际上是 Stackoverflow 本身使用的! See this answer for reference。
huntsbot.com聚合了超过10+全球外包任务平台的外包需求,寻找外包任务与机会变的简单与高效。
自动复制到剪贴板可能很危险,因此大多数浏览器(Internet Explorer 除外)都使其变得非常困难。就个人而言,我使用以下简单技巧:
function copyToClipboard(text) {
window.prompt("Copy to clipboard: Ctrl+C, Enter", text);
}
向用户呈现提示框,其中已选择要复制的文本。现在按下 Ctrl + C 和 Enter(关闭框)就足够了——瞧!
现在剪贴板复制操作是安全的,因为用户手动进行(但以一种非常简单的方式)。当然,它适用于所有浏览器。
这是我要复制的 function copyToClipboard(text) { window.prompt(“复制到剪贴板:Ctrl+C, Enter”, text); } 脚本>
但是该对话框中显示的字符数量有限制,因此要复制的数据量也有限制。
聪明,但这只支持单行。
将“提示”功能更改为自定义模式很简单,诀窍的核心是使用可编辑的内容字段并预先选择文本,并且它不会通过强制用户使用来破坏浏览器 UI自己行动。一个++
如果您的文本超过 2000 个字符,它将被截断,但对于较小的文本样本,它的效果很好
@RasTheDestroyer - 2k 字符截断似乎是 Chrome 的问题,但不管怎样,很高兴知道
打造属于自己的副业,开启自由职业之旅,从huntsbot.com开始!
以下方法适用于 Chrome、Firefox、Internet Explorer 和 Edge,以及最新版本的 Safari(2016 年 10 月发布的版本 10 中添加了复制支持)。
创建一个 textarea 并将其内容设置为要复制到剪贴板的文本。
将文本区域附加到 DOM。
选择文本区域中的文本。
调用 document.execCommand(“copy”)
从 dom 中删除 textarea。
注意:您不会看到 textarea,因为它是在 Javascript 代码的同一个同步调用中添加和删除的。
如果您自己实现此功能,请注意以下几点:
出于安全原因,这只能从诸如 click 之类的事件处理程序中调用(就像打开窗口一样)。
Internet Explorer 将在第一次更新剪贴板时显示权限对话框。
Internet Explorer 和 Edge 将在 textarea 获得焦点时滚动。
execCommand() 在某些情况下可能会抛出。
除非您使用 textarea,否则换行符和制表符可能会被吞下。 (大多数文章似乎都建议使用 div)
当 Internet Explorer 对话框显示时,textarea 将可见,您要么需要隐藏它,要么使用 Internet Explorer 特定的 clipboardData API。
在 Internet Explorer 中,系统管理员可以禁用剪贴板 API。
下面的函数应该尽可能干净地处理以下所有问题。如果您发现任何问题或有任何改进建议,请发表评论。
// Copies a string to the clipboard. Must be called from within an
// event handler such as click. May return false if it failed, but
// this is not always possible. Browser support for Chrome 43+,
// Firefox 42+, Safari 10+, Edge and Internet Explorer 10+.
// Internet Explorer: The clipboard feature may be disabled by
// an administrator. By default a prompt is shown the first
// time the clipboard is used (per session).
function copyToClipboard(text) {
if (window.clipboardData && window.clipboardData.setData) {
// Internet Explorer-specific code path to prevent textarea being shown while dialog is visible.
return window.clipboardData.setData("Text", text);
}
else if (document.queryCommandSupported && document.queryCommandSupported("copy")) {
var textarea = document.createElement("textarea");
textarea.textContent = text;
textarea.style.position = "fixed"; // Prevent scrolling to bottom of page in Microsoft Edge.
document.body.appendChild(textarea);
textarea.select();
try {
return document.execCommand("copy"); // Security exception may be thrown by some browsers.
}
catch (ex) {
console.warn("Copy to clipboard failed.", ex);
return prompt("Copy to clipboard: Ctrl+C, Enter", text);
}
finally {
document.body.removeChild(textarea);
}
}
}
https://jsfiddle.net/fx6a6n6x/
huntsbot.com提供全网独家一站式外包任务、远程工作、创意产品分享与订阅服务!
不错的答案:跨浏览器支持,错误处理+清理。从今天对 queryCommandSupported 的新支持开始,复制到剪贴板现在在 Javascript 中是可行的,这应该是公认的答案,而不是笨拙的 'window.prompt("Copy to clipboard: Ctrl+C, Enter", text)' 解决方法。 IE9支持window.clipboardData,所以你应该在浏览器支持列表中添加IE9,我认为IE8及之前的版本也可能,但需要验证。
@SantiagoCorredoira:在 2016 年,这应该是公认的答案。请考虑重新分配 BGT(绿色大勾号)。
@Noitidart 我测试过,它非常适用于 firefox 54、chrome 60 和边缘浏览器,即使焦点不在 html 文档中,您遇到的错误也可能特定于 FF 55 版本
@Noitidart 它在这里仍然可以完美运行,专注于开发工具并没有阻止它。顺便说一句,普通的网络应用用户会在开发者工具上做什么
jQuery UI 用户:请注意,如果您尝试从模式对话框中使用此功能,您将遇到此方法的问题。我怀疑这是因为 jQuery UI 模式正在管理/操作文档焦点。如果它适合您的用例,一种解决方法是先关闭模式对话框,然后复制文本。或者,简单地使用非模态对话框。我怀疑您也可以修改此函数,以便将文本区域添加到模态而不是正文。
huntsbot.com精选全球7大洲远程工作机会,涵盖各领域,帮助想要远程工作的数字游民们能更精准、更高效的找到对方。
这是我对那个的看法…
function copy(text) {
var input = document.createElement('input');
input.setAttribute('value', text);
document.body.appendChild(input);
input.select();
var result = document.execCommand('copy');
document.body.removeChild(input);
return result;
}
@korayem:请注意,使用 html input
字段不会尊重换行符 \n
并将任何文本展平为一行。
正如@nikksan 在评论中提到的那样,使用 textarea
将解决以下问题:
function copy(text) {
var input = document.createElement('textarea');
input.innerHTML = text;
document.body.appendChild(input);
input.select();
var result = document.execCommand('copy');
document.body.removeChild(input);
return result;
}
@sof-03 使用 textarea 代替 input 并添加 \r\n 换行
无法在 Win10x64 上的 Microsoft Edge 42.17134.1.0 中工作
我已经复制了你的答案。它适用于 chrome,这就是我所需要的。
这是适用于 Firefox v68.0.2(64 位)的最简单的解决方案。
出于某种原因,我通常的“创建一个隐藏的输入或文本区域,然后选择它并执行命令”不起作用,这是迄今为止列出的最佳解决方案,尽管其他解决方案很全面,并且像完整的维基百科页面一样,这个效果很好对我来说,所以+1
huntsbot.com – 高效赚钱,自由工作
从网页读取和修改剪贴板会引发安全和隐私问题。但是,在 Internet Explorer 中,可以做到这一点。我找到了这个 example snippet: