ChatGPT解决这个技术问题 Extra ChatGPT

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

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

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

没什么特别的。他们可以自己做,但我还想提供点击按钮的可能性,而不必担心选择正确的文本部分。
它在 IE 和 FF 中给浏览器未定义的异常
如果我们可以将文本放入用户的剪贴板,我们就可以毁掉他的剪贴板。
就个人而言,我更喜欢第 3 方,例如 clipboardjs。 clipboardjs:clipboardjs.com vue-clipboards:zhuowenli.github.io/vue-clipboards v-clipboard:vuejsexamples.com/a-clipboard-library-with-vue-js

b
barhatsor

概述

有三个主要的浏览器 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'); });



< 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>

复杂示例:复制到剪贴板而不显示输入

如果屏幕上可以看到 textareainput 元素,上述简单示例非常有效。

在某些情况下,您可能希望将文本复制到剪贴板而不显示 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'); });



< 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.execCommanddocument.queryCommandSupporteddocument.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
P
Peter Mortensen

自动复制到剪贴板可能很危险,因此大多数浏览器(Internet Explorer 除外)都使其变得非常困难。就个人而言,我使用以下简单技巧:

function copyToClipboard(text) {
  window.prompt("Copy to clipboard: Ctrl+C, Enter", text);
}

向用户呈现提示框,其中已选择要复制的文本。现在按下 Ctrl + C 和 Enter(关闭框)就足够了——瞧!

现在剪贴板复制操作是安全的,因为用户手动进行(但以一种非常简单的方式)。当然,它适用于所有浏览器。


使用 flash 进行简单的复制操作似乎有点矫枉过正,很高兴有一种干净的 JS 方法可以做到这一点。而且由于我们处于企业环境中。 IE很好。谢谢班迪!
请解释一下 execCommand(\\’copy\\’); 的作用,如果不复制到 IE 的剪贴板? @mrBorna
不要使用 if(!document.all)if(!r.execCommand) 以免其他人实现它! Document.all 与此完全无关。
当人们使用 Flash 更改剪贴板时,为什么十年来从未提出过这些隐私问题?如果我们只允许一种方式(即复制,而不是阅读其内容),这如何产生隐私问题?
@MuhammadbinYusrat:虽然不是隐私问题,但它是用户体验问题。假设用户复制了一些东西,并认为他知道剪贴板上的内容,然后浏览您的网站,突然剪贴板中包含他没有要求的东西,他丢失了他最初复制的内容。
P
Peter Mortensen

如果您想要一个非常简单的解决方案(集成时间不到 5 分钟)并且开箱即用看起来不错,那么 Clippy 是一些更复杂解决方案的不错替代方案。

它是由 GitHub 的联合创始人编写的。下面的示例 Flash 嵌入代码:

<object
    classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
    width="110"
    height="14"
    id="clippy">

    <param name="movie" value="/flash/clippy.swf"/>
    <param name="allowScriptAccess" value="always"/>
    <param name="quality" value="high"/>
    <param name="scale" value="noscale"/>
    <param NAME="FlashVars" value="text=#{text}"/>
    <param name="bgcolor" value="#{bgcolor}"/>
    <embed
        src="/flash/clippy.swf"
        width="110"
        height="14"
        name="clippy"
        quality="high"
        allowScriptAccess="always"
        type="application/x-shockwave-flash"
        pluginspage="http://www.macromedia.com/go/getflashplayer"
        FlashVars="text=#{text}"
        bgcolor="#{bgcolor}"/>
</object>

请记住将 #{text} 替换为您需要复制的文本,并将 #{bgcolor} 替换为颜色。


对于任何感兴趣的人,请在复制 repo 的 URL 时检查在 GitHub 上使用的 Clippy。
R
Richard Shurtz

我最近就这个问题写了一篇technical blog post(我在 Lucidchart 工作,我们最近对剪贴板进行了大修)。

将纯文本复制到剪贴板相对简单,假设您尝试在系统复制事件期间执行此操作(用户按 Ctrl + C 或使用浏览器的菜单)。

var isIe = (navigator.userAgent.toLowerCase().indexOf("msie")    != -1 ||
            navigator.userAgent.toLowerCase().indexOf("trident") != -1);

document.addEventListener('copy', function(e) {
    var textToPutOnClipboard = "This is some text";
    if (isIe) {
        window.clipboardData.setData('Text', textToPutOnClipboard);
    } else {
        e.clipboardData.setData('text/plain', textToPutOnClipboard);
    }
    e.preventDefault();
});

不在系统复制事件期间将文本放在剪贴板上要困难得多。看起来这些其他答案中的一些参考了通过 Flash 进行操作的方法,这是唯一的跨浏览器方法(据我所知)。

除此之外,还有一些基于浏览器的选项。

这是 Internet Explorer 中最简单的方法,您可以随时通过 JavaScript 访问 clipboardData 对象:

window.clipboardData

(但是,当您尝试在系统剪切、复制或粘贴事件之外执行此操作时,Internet Explorer 将提示用户授予 Web 应用程序剪贴板权限。)

在 Chrome 中,您可以创建一个 Chrome 扩展程序,它会为您提供 clipboard permissions(这是我们为 Lucidchart 所做的)。然后对于安装了您的扩展程序的用户,您只需要自己触发系统事件:

document.execCommand('copy');

看起来 Firefox 有 some options 允许用户授予某些网站访问剪贴板的权限,但我没有亲自尝试过这些。


博文中没有提到(我希望在不久的将来更新它),是使用 execCommand 触发剪切和复制的能力。这在 IE10+、Chrome 43+ 和 Opera29+ 中受支持。在这里阅读它。 updates.html5rocks.com/2015/04/cut-and-copy-commands
这样做的一个问题是它劫持了其他正常的复制事件。
注意!这种浏览器嗅探很糟糕。做特征嗅探。你让 IE 很难更新。
J
Josh Crozier

我喜欢这个:

<input onclick="this.select();" type='text' value='copy me' />

如果用户不知道如何在他们的操作系统中复制文本,那么他们很可能也不知道如何粘贴。因此,只需自动选择它,其余的留给用户。


我也喜欢它,因为它很短。您也可以复制:<input onclick="this.select(); document.execCommand('copy');" type='text' value='copy me' />
t
tripulse

clipboard.js 是一个小型非 Flash 实用程序,允许将文本或 HTML 数据复制到剪贴板。它非常易于使用,只需包含 .js 并使用如下内容:

<button id='markup-copy'>Copy Button</button>

<script>
document.getElementById('markup-copy').addEventListener('click', function() {
  clipboard.copy({
    'text/plain': 'Markup text. Paste me into a rich text editor.',
    'text/html': '<i>here</i> is some <b>rich text</b>'
  }).then(
    function(){console.log('success'); },
    function(err){console.log('failure', err);
  });

});
</script>

clipboard.js 也在 GitHub 上。

注意:现在已弃用。迁移到这里。


该库被 angular.io 用于其英雄之旅,并通过显示用户只需复制的预选文本以优雅模式回退不支持 execCommand 的浏览器。
看起来 clipboard.js 已被替换或分叉,但它似乎仍然存在并在 npmjs.com/package/clipboard 积极维护
P
Peter Mortensen

在 2018 年,您可以这样做:

async copySomething(text?) {
  try {
    const toCopy = text || location.href;
    await navigator.clipboard.writeText(toCopy);
    console.log('Text or Page URL copied');
  }
  catch (err) {
    console.error('Failed to copy: ', err);
  }
}

它在我的 Angular 6+ 代码中使用,如下所示:

<button mat-menu-item (click)="copySomething()">
    <span>Copy link</span>
</button>

如果我传入一个字符串,它会复制它。如果没有,它会复制页面的 URL。

剪贴板的东西也可以做更多的体操。在此处查看更多信息:

Unblocking Clipboard Access


您已链接到本地主机
请注意,这在 Safari(版本 11.1.2)中不起作用
@arjun27 好吧,希望有一天苹果能赶上。尽管此 caniuse.com/#feat=clipboard 显示您提到的上述版本被部分支持。
我得到两个函数 readText, writeText 一个处于拒绝状态的 Promise
根据提供的链接,“navigator.clipboard 仅支持通过 HTTPS 提供的页面”
G
Grim

我非常成功地使用了它(没有 jQuery 或任何其他框架)。

function copyToClp(txt){
    var m = document;
    txt = m.createTextNode(txt);
    var w = window;
    var b = m.body;
    b.appendChild(txt);
    if (b.createTextRange) {
        var d = b.createTextRange();
        d.moveToElementText(txt);
        d.select();
        m.execCommand('copy');
    } 
    else {
        var d = m.createRange();
        var g = w.getSelection;
        d.selectNodeContents(txt);
        g().removeAllRanges();
        g().addRange(d);
        m.execCommand('copy');
        g().removeAllRanges();
    }
    txt.remove();
}

警告

制表符被转换为空格(至少在 Chrome 中)。


在 Firefox 上不起作用,我收到一条错误消息,提示缺少用户激活
@Luke_ Firefox 对吗?您是否在没有直接用户点击的情况下调用它?
P
Peter Mortensen

ZeroClipboard 是我发现的最好的跨浏览器解决方案:

<div id="copy" data-clipboard-text="Copy Me!">Click to copy</div>
<script src="ZeroClipboard.js"></script>
<script>
  var clip = new ZeroClipboard( document.getElementById('copy') );
</script>

如果您需要对 iOS 的非 Flash 支持,您只需添加一个备用:

clip.on( 'noflash', function ( client, args ) {
    $("#copy").click(function(){
        var txt = $(this).attr('data-clipboard-text');
        prompt ("Copy link, then click OK.", txt);
    });
});

http://zeroclipboard.org/

https://github.com/zeroclipboard/ZeroClipboard


使用 Flash 跨浏览器?不适用于 iOS 和 Android 4.4
请参阅更新的答案。这允许闪存用户的步骤更少,并为其他所有人提供后备。
它有十亿行代码。这绝对是嘲笑。最好不要这样做,而不是在项目中包含这样的怪物
有一个简单的版本 gist.github.com/JamesMGreene/8698897,它是 20K,它没有 74k 版本中的所有花里胡哨。两者都不是很大。我的猜测是大多数用户都可以接受下载 74k 或 20k 文件所花费的额外毫秒数,因此复制/粘贴只需单击一次而不是两次。
@Justin即使我复制并粘贴示例,我也无法使其在本地工作(我进行了最少的更改,例如脚本标签中的 src 的值)。我觉得他们的文档很漂亮但效率低下。
P
Peter Mortensen

由于 Chrome 42+ 和 Firefox 41+ 现在支持 document.execCommand('copy') 命令,我使用以下组合创建了几个函数用于跨浏览器复制到剪贴板功能1} 和 Google Developer's answer

function selectElementContents(el) { // 复制 textarea、pre、div 等 if (document.body.createTextRange) { // Internet Explorer var textRange = document.body.createTextRange(); textRange.moveToElementText(el); textRange.select(); textRange.execCommand("复制"); } else if (window.getSelection && document.createRange) { // 非 Internet Explorer var range = document.createRange(); range.selectNodeContents(el); var sel = window.getSelection(); sel.removeAllRanges(); sel.addRange(范围);尝试 { var 成功 = document.execCommand('copy'); var msg = 成功? '成功' : '不成功'; console.log('复制命令是' + msg); } catch (err) { console.log('糟糕,无法复制'); } } } // 结束函数 selectElementContents(el) function make_copy_button(el) { var copy_btn = document.createElement('input'); copy_btn.type = "按钮"; el.parentNode.insertBefore(copy_btn, el.nextSibling); copy_btn.onclick = function() { selectElementContents(el); }; if (document.queryCommandSupported("copy") || parseInt(navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./)[2]) >= 42) { // 复制适用于 Internet Explorer 4+、Chrome 42+、Firefox 41+、Opera 29+ copy_btn.value = "复制到剪贴板"; } else { // 仅选择 Safari 和旧版 Chrome、Firefox 和 Opera copy_btn.value = "全选(然后按 Ctrl + C 复制)"; } } /* 注意:document.queryCommandSupported("copy") 应该在支持复制的浏览器上返回“true”,但 Chrome 版本 42 到 47 中存在一个错误,使其返回“false”。所以在那些版本的 Chrome 中,功能检测不起作用!见 https://code.google.com/p/chromium/issues/detail?id=476508 */ make_copy_button(document.getElementById("markup"));

 可以通过跨浏览器支持复制或选择的文本。 


感谢您总结这一点!您的代码中有一些错误:您定义了两次“范围”变量(var range = document.createRange())。
你是对的@ChristianEngel。我已经删除了第二个。我不知道它是怎么进来的。
你好杰夫如果我想自定义“复制到剪贴板”怎么办。请帮忙!
S
SanTasso

$("td").click(function (e) { var clickedCell = $(e.target).closest("td"); navigator.clipboard.writeText(clickedCell.text()); alert(clickedCell.text( )); });

First < /tr>
第二
第三
第四

我已经阅读了所有答案,截至 2020 年 6 月 1 日,当我终于找到文档时,我一直在努力解决这个问题:

$("td").click(function (e) {
    var clickedCell = $(e.target).closest("td");
    navigator.clipboard.writeText(clickedCell.text());
});

它将单击的单元格文本写入浏览器剪贴板。

您可以根据需要更改选择器“td”,您可以添加 console.log 以进行调试和/或警报功能。

这是文档:https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/writeText


没有IE兼容性
P
Peter Mortensen

在我从事的一个项目中,一个利用 ZeroClipboard 库的 jQuery 复制到剪贴板插件。

如果你是一个重度 jQuery 用户,它比原生的 Zero Clipboard 插件更容易使用。


92kb 并没有那么大,它运行速度很快如果您愿意,可以使用 text() 而不是 innerHTML()..
@John:innerHTML 已经支持跨浏览器很长时间了。仅仅因为微软最初提出了这个想法,它并没有使它不可靠或专有。它现在也终于被添加到官方规范中(在每个主要浏览器供应商都已经添加了对它的支持之后......sigh)。
@John您抱怨 jQuery 在使用 Flash 的答案中不够 JavaScripty ;)
在大多数情况下,innerHTML 比替代方案要好。下马!它更快、更高效,并且不需要重新渲染页面。
@RozzA 92KB 真的很大。在 LTE 成熟之前,GPRSWW mobile data standard,它从 1 KB/s 开始。自己算算。
A
Andhi Irawan

我把我认为最好的一个放在一起。

使用 cssText 来避免 Internet Explorer 中的异常,而不是直接使用样式。

如果有选择,则恢复选择

设置为只读,这样键盘就不会出现在移动设备上

有一个适用于 iOS 的解决方法,因此它实际上可以正常工作,因为它通常会阻止 execCommand。

这里是:

const copyToClipboard = (function initClipboardText() {
  const textarea = document.createElement('textarea');

  // Move it off-screen.
  textarea.style.cssText = 'position: absolute; left: -99999em';

  // Set to readonly to prevent mobile devices opening a keyboard when
  // text is .select()'ed.
  textarea.setAttribute('readonly', true);

  document.body.appendChild(textarea);

  return function setClipboardText(text) {
    textarea.value = text;

    // Check if there is any content selected previously.
    const selected = document.getSelection().rangeCount > 0 ?
      document.getSelection().getRangeAt(0) : false;

    // iOS Safari blocks programmatic execCommand copying normally, without this hack.
    // https://stackoverflow.com/questions/34045777/copy-to-clipboard-using-javascript-in-ios
    if (navigator.userAgent.match(/ipad|ipod|iphone/i)) {
      const editable = textarea.contentEditable;
      textarea.contentEditable = true;
      const range = document.createRange();
      range.selectNodeContents(textarea);
      const sel = window.getSelection();
      sel.removeAllRanges();
      sel.addRange(range);
      textarea.setSelectionRange(0, 999999);
      textarea.contentEditable = editable;
    }
    else {
      textarea.select();
    }

    try {
      const result = document.execCommand('copy');

      // Restore previous selection.
      if (selected) {
        document.getSelection().removeAllRanges();
        document.getSelection().addRange(selected);
      }

      return result;
    }
    catch (err) {
      console.error(err);
      return false;
    }
  };
})();

用法:copyToClipboard('some text')


在 Opera 等中不起作用。
E
Enyby

我找到了以下解决方案:

on-key-down 处理程序创建一个“pre”标签。我们将要复制的内容设置到此标签,然后在此标签上进行选择并在处理程序中返回 true。这会调用 Chrome 的标准处理程序并复制选定的文本。

如果需要,您可以为恢复先前选择的功能设置超时。我在 MooTools 上的实现:

function EnybyClipboard() {
    this.saveSelection = false;
    this.callback = false;
    this.pastedText = false;

    this.restoreSelection = function() {
        if (this.saveSelection) {
            window.getSelection().removeAllRanges();
            for (var i = 0; i < this.saveSelection.length; i++) {
                window.getSelection().addRange(this.saveSelection[i]);
            }
            this.saveSelection = false;
        }
    };

    this.copyText = function(text) {
        var div = $('special_copy');
        if (!div) {
            div = new Element('pre', {
                'id': 'special_copy',
                'style': 'opacity: 0;position: absolute;top: -10000px;right: 0;'
            });
            div.injectInside(document.body);
        }
        div.set('text', text);
        if (document.createRange) {
            var rng = document.createRange();
            rng.selectNodeContents(div);
            this.saveSelection = [];
            var selection = window.getSelection();
            for (var i = 0; i < selection.rangeCount; i++) {
                this.saveSelection[i] = selection.getRangeAt(i);
            }
            window.getSelection().removeAllRanges();
            window.getSelection().addRange(rng);
            setTimeout(this.restoreSelection.bind(this), 100);
        } else return alert('Copy did not work. :(');
    };

    this.getPastedText = function() {
        if (!this.pastedText) alert('Nothing to paste. :(');
        return this.pastedText;
    };

    this.pasteText = function(callback) {
        var div = $('special_paste');
        if (!div) {
            div = new Element('textarea', {
                'id': 'special_paste',
                'style': 'opacity: 0;position: absolute;top: -10000px;right: 0;'
            });
            div.injectInside(document.body);
            div.addEvent('keyup', function() {
                if (this.callback) {
                    this.pastedText = $('special_paste').get('value');
                    this.callback.call(null, this.pastedText);
                    this.callback = false;
                    this.pastedText = false;
                    setTimeout(this.restoreSelection.bind(this), 100);
                }
            }.bind(this));
        }
        div.set('value', '');
        if (document.createRange) {
            var rng = document.createRange();
            rng.selectNodeContents(div);
            this.saveSelection = [];
            var selection = window.getSelection();
            for (var i = 0; i < selection.rangeCount; i++) {
                this.saveSelection[i] = selection.getRangeAt(i);
            }
            window.getSelection().removeAllRanges();
            window.getSelection().addRange(rng);
            div.focus();
            this.callback = callback;
        } else return alert('Failed to paste. :(');
    };
}

用法:

enyby_clip = new EnybyClipboard(); // Init

enyby_clip.copyText('some_text'); // Place this in the Ctrl+C handler and return true;

enyby_clip.pasteText(function callback(pasted_text) {
    alert(pasted_text);
}); // Place this in Ctrl+V handler and return true;

在粘贴时,它会创建一个文本区域并以相同的方式工作。

PS:也许这个解决方案可以用来创建一个没有 Flash 的完整的跨浏览器解决方案。它适用于 Firefox 和 Chrome。


有人试过吗?听起来很不错,以防它真的适用于一系列浏览器!
jsfiddle.net/H2FHC 演示:fiddle.jshell.net/H2FHC/show 请打开它并按 Ctrl+V 或 Ctrl+C。在 FF 19.0 中完美分叉。在 Chrome 25.0.1364.97 m 中也是如此。歌剧 12.14 - 好的。适用于 Windows 的 Safari 5.1.7 - 好的。 IE - 失败。
对于 IE 需要在页面内的元素上运行焦点。请参阅 fiddle.jshell.net/H2FHC/3/showfiddle.jshell.net/H2FHC/3 在 IE 9/10 中工作。 IE 6/7 需要以其他方式创建选择,因为不支持 document.createRange。
P
Peter Mortensen

其他方法会将纯文本复制到剪贴板。要复制 HTML(即,您可以将结果粘贴到所见即所得的编辑器中),您只能在 Internet Explorer 中执行以下操作。这与其他方法根本不同,因为浏览器实际上是在可见地选择内容。

// Create an editable DIV and append the HTML content you want copied
var editableDiv = document.createElement("div");
with (editableDiv) {
    contentEditable = true;
}
editableDiv.appendChild(someContentElement);

// Select the editable content and copy it to the clipboard
var r = document.body.createTextRange();
r.moveToElementText(editableDiv);
r.select();
r.execCommand("Copy");

// Deselect, so the browser doesn't leave the element visibly selected
r.moveToElementText(someHiddenDiv);
r.select();

在此处查看更完整的 HTML 解决方案stackoverflow.com/questions/34191780/…
T
Tauseef Arshad

JavaScript/TypeScript 中最好和最简单的方法使用这个命令

navigator.clipboard.writeText(textExample);

只需在 textExample 中传递您想要复制到剪贴板的值


navigator.clipboard 可以自定义。你应该抓住这个异常......
不适用于IOS
H
HO LI Pin

此代码在 2021 年 5 月测试。在 Chrome、IE、Edge 上工作。下面的“消息”参数是您要复制的字符串值。

<script type="text/javascript">
    function copyToClipboard(message) {
        var textArea = document.createElement("textarea");
        textArea.value = message;
        textArea.style.opacity = "0"; 
        document.body.appendChild(textArea);
        textArea.focus();
        textArea.select();


        try {
            var successful = document.execCommand('copy');
            var msg = successful ? 'successful' : 'unsuccessful';
            alert('Copying text command was ' + msg);
        } catch (err) {
            alert('Unable to copy value , error : ' + err.message);
        }

        document.body.removeChild(textArea);
    }

</script>

我最喜欢这个
P
Peter Mortensen

从 Flash 10 开始,如果操作源自用户与 Flash 对象的交互,则只能复制到剪贴板。 (Read the related section from Adobe's Flash 10 announcement。)

解决方案是在 Copy 按钮或启动复制的任何元素上方覆盖 Flash 对象。 ZeroClipboard 是目前具有此实现的最佳库。经验丰富的 Flash 开发人员可能只想制作自己的库。


P
Peter Mortensen

我找到了以下解决方案:

我在隐藏输入中有文本。因为 setSelectionRange 对隐藏输入不起作用,所以我暂时将类型更改为文本,复制文本,然后再次将其隐藏。如果要从元素复制文本,可以将其传递给函数并将其内容保存在目标变量中。

jQuery('#copy').on('click', function () {
    copyToClipboard();
});

function copyToClipboard() {
    var target = jQuery('#hidden_text');

    // Make it visible, so can be focused
    target.attr('type', 'text');
    target.focus();
    // Select all the text
    target[0].setSelectionRange(0, target.val().length);

    // Copy the selection
    var succeed;
    try {
        succeed = document.execCommand("copy");
    }
    catch (e) {
        succeed = false;
    }

    // Hide input again
    target.attr('type', 'hidden');

    return succeed;
}

P
Peter Mortensen

将文本从 HTML 输入复制到剪贴板:

function myFunction() { /* 获取文本字段 */ var copyText = document.getElementById("myInput"); /* 选择文本字段 */ copyText.select(); /* 复制文本字段内的文本 */ document.execCommand("Copy"); /* 警告复制的文本 */ alert("复制的文本:" + copyText.value); }

注意: Internet Explorer 9 及更早版本不支持 document.execCommand() 方法。

来源W3Schools - Copy Text to Clipboard


C
Codebeat

已经有很多答案,但是想添加一个(jQuery)。适用于任何浏览器,也适用于移动浏览器(即,关于安全性的提示,但当您接受它时,它就可以正常工作)。

function appCopyToClipBoard(sText)
{
    var oText = false,
        bResult = false;
    try
    {
        oText = document.createElement("textarea");
        $(oText).addClass('clipboardCopier').val(sText).insertAfter('body').focus();
        oText.select();
        document.execCommand("Copy");
        bResult = true;
    }
    catch(e) {
    }

    $(oText).remove();
    return bResult;
}

在您的代码中:

if (!appCopyToClipBoard('Hai there! This is copied to the clipboard.'))
{
    alert('Sorry, copy to clipboard failed.');
}

T
Tauseef Arshad

复制文本字段内文本的最佳方法。使用 navigator.clipboard.writeText。

<input type="text" value="Hello World" id="myId">
<button onclick="myFunction()" >Copy text</button>

<script>
function myFunction() {
  var copyText = document.getElementById("myId");
  copyText.select();
  copyText.setSelectionRange(0, 99999);
  navigator.clipboard.writeText(copyText.value);
}

</script>

document.execCommand('复制');命令总是不起作用,上面的方法解决了它
document.execCommand('复制');命令有效,但不推荐使用 'document.execCommand' 的签名 '(commandId: string, showUI?: boolean | undefined, value?: string | undefined): boolean'
P
Peter Mortensen

从(类似于 Excel)构建自定义网格编辑以及与 Excel 的兼容性时,我遇到了同样的问题。我必须支持选择多个单元格、复制和粘贴。

解决方案:创建一个文本区域,您将在其中插入数据供用户复制(对于我来说,当用户选择单元格时),将焦点设置在它上面(例如,当用户按下 Ctrl 时)并选择整个文本。

因此,当用户按 Ctrl + C 时,他/她会复制他/她选择的单元格。测试后,只需将 textarea 的大小调整为一个像素(我没有测试它是否可以在 display:none 上工作)。它适用于所有浏览器,并且对用户透明。

粘贴 - 你可以这样做(在你的目标上有所不同) - 继续关注 textarea 并使用 onpaste 捕获粘贴事件(在我的项目中,我在单元格中使用 textareas 进行编辑)。

我无法粘贴示例(商业项目),但您明白了。


y
yurenchen

这是其他答案之间的一些组合。

var copyToClipboard = function(textToCopy){
    $("body")
        .append($('<textarea name="fname" class="textToCopyInput"/>' )
        .val(textToCopy))
        .find(".textToCopyInput")
        .select();
      try {
        var successful = document.execCommand('copy');
        var msg = successful ? 'successful' : 'unsuccessful';
        alert('Text copied to clipboard!');
      } catch (err) {
          window.prompt("To copy the text to clipboard: Ctrl+C, Enter", textToCopy);
      }
     $(".textToCopyInput").remove();
}

它使用 jQuery,但它当然不是必须的。如果你愿意,你可以改变它。我只是有 jQuery 供我使用。您还可以添加一些 CSS 以确保不显示输入。例如:

.textToCopyInput{opacity: 0; position: absolute;}

或者当然你也可以做一些内联样式

.append($('<textarea name="fname" style="opacity: 0;  position: absolute;" class="textToCopyInput"/>' )

如何直接从变量数据中复制。即:var str = "word"; ?
变量 msg 未使用
最好使用'<textarea class="textToCopyInput"/></textarea>'如果 textToCopy 包含 \n
P
Peter Mortensen

在 Internet Explorer 以外的浏览器中,您需要使用一个小的 Flash 对象来操作剪贴板,例如

自动复制到剪贴板


这现在已经过时了...查看 GvS 的建议
GvS 的建议使用 Flash 电影?这不是同一个想法吗?
P
Peter Mortensen
function copytoclipboard(element) {

    var $temp = $("<input>");
    $("body").append($temp);
    $temp.val('0' + element).select();
    document.execCommand("copy");
    $temp.remove();
}

谢谢你,你是救生员
j
jbyrd

Stackoverflow 的解决方案

我只是想指出 Stackoverflow 实际上就是这样做的。在每个答案下都有一个“共享”链接 - 当您单击该链接时,它会打开一个弹出窗口,其中在输入中突出显示共享链接,以及一个“复制链接”链接:

https://i.stack.imgur.com/ZpqQ3.png

如果你去 Chrome DevTools 并去那个链接的事件监听器,你可以找到他们使用的函数。它被称为 tryCopy():

https://i.stack.imgur.com/cqeGw.png

这与 Dean Taylors answer here(最近更新)完全一致 - 请特别阅读标题为 “Async + Fallback” 的部分。 TL;DR 是:尝试使用 navigator.clipboard api - 如果浏览器不支持,请退回到 document.execCommand()。


嗨,我想知道您是否设法让这个或 Dean Taylors 解决方案与 IOS 一起使用?