如何在 JavaScript 中复制到剪贴板?

问题描述:

如何将文本复制到剪贴板(多浏览器)?

相关:How does Trello access the user’s clipboard?

解决方案1:

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。

解决方案2:

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 的问题,但不管怎样,很高兴知道

解决方案3:

打造属于自己的副业,开启自由职业之旅,从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 模式正在管理/操作文档焦点。如果它适合您的用例,一种解决方法是先关闭模式对话框,然后复制文本。或者,简单地使用非模态对话框。我怀疑您也可以修改此函数,以便将文本区域添加到模态而不是正文。

解决方案4:

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

解决方案5:

huntsbot.com – 高效赚钱,自由工作

从网页读取和修改剪贴板会引发安全和隐私问题。但是,在 Internet Explorer 中,可以做到这一点。我找到了这个 example snippet

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值