4040

将文本复制到剪贴板(多浏览器)的最佳方法是什么?

我试过了:

function copyToClipboard(text) {
    if (window.clipboardData) { // Internet Explorer
        window.clipboardData.setData("Text", text);
    } else {
        unsafeWindow.netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
        const clipboardHelper = Components.classes["@mozilla.org/widget/clipboardhelper;1"].getService(Components.interfaces.nsIClipboardHelper);
        clipboardHelper.copyString(text);
    }
}

但在 Internet Explorer 中,它给出了语法错误。在 Firefox 中,它说unsafeWindow is not defined

一个不使用Flash的好技巧:Trello 如何访问用户的剪贴板?

4

67 回答 67

3006

概述

有三个主要的浏览器 API 用于复制到剪贴板:

  1. 异步剪贴板 API [navigator.clipboard.writeText]

    • Chrome 66中提供以文本为中心的部分(2018 年 3 月)
    • 访问是异步的并使用JavaScript Promises,可以编写为安全用户提示(如果显示)不会中断页面​​中的 JavaScript。
    • 文本可以直接从变量复制到剪贴板。
    • 仅在通过 HTTPS 提供的页面上受支持。
    • 在 Chrome 66 页面中,非活动标签可以在没有权限提示的情况下写入剪贴板。
  2. document.execCommand('copy')已弃用

    • 自 2015 年 4 月起,大多数浏览器都支持此功能(请参阅下面的浏览器支持)。
    • 访问是同步的,即停止页面中的 JavaScript 直到完成,包括显示和用户与任何安全提示进行交互。
    • 文本从 DOM 中读取并放置在剪贴板上。
    • 在测试期间 ~ 2015 年 4 月,只有 Internet Explorer 被记录为在写入剪贴板时显示权限提示。
  3. 覆盖复制事件

    • 请参阅有关覆盖复制事件的剪贴板 API 文档。
    • 允许您从任何复制事件修改剪贴板上显示的内容,可以包括纯文本以外的其他格式的数据。
    • 这里没有涉及,因为它没有直接回答这个问题。

一般开发说明

当您在控制台中测试代码时,不要期望剪贴板相关命令能够正常工作。通常,页面需要处于活动状态(异步剪贴板 API)或需要用户交互(例如用户单击)以允许 ( document.execCommand('copy')) 访问剪贴板,详情请参见下文。

重要(此处注明 2020/02/20)

请注意,由于这篇文章最初是写在跨域IFRAME和其他IFRAME “沙盒”中的权限的弃用,因此会阻止嵌入式演示“运行代码片段”按钮和“codepen.io 示例”在某些浏览器中工作(包括 Chrome 和 Microsoft Edge )。

要开发创建您自己的网页,请通过 HTTPS 连接提供该页面以进行测试和开发。

这是一个演示代码工作的测试/演示页面: https ://deanmarktaylor.github.io/clipboard-test/

异步+后备

由于浏览器对新 Async Clipboard API 的支持级别,您可能希望回退到该document.execCommand('copy')方法以获得良好的浏览器覆盖率。

这是一个简单的示例(可能无法嵌入此站点,请阅读上面的“重要”说明):

function fallbackCopyTextToClipboard(text) {
  var textArea = document.createElement("textarea");
  textArea.value = text;
  
  // Avoid scrolling to bottom
  textArea.style.top = "0";
  textArea.style.left = "0";
  textArea.style.position = "fixed";

  document.body.appendChild(textArea);
  textArea.focus();
  textArea.select();

  try {
    var successful = document.execCommand('copy');
    var msg = successful ? 'successful' : 'unsuccessful';
    console.log('Fallback: Copying text command was ' + msg);
  } catch (err) {
    console.error('Fallback: Oops, unable to copy', err);
  }

  document.body.removeChild(textArea);
}
function copyTextToClipboard(text) {
  if (!navigator.clipboard) {
    fallbackCopyTextToClipboard(text);
    return;
  }
  navigator.clipboard.writeText(text).then(function() {
    console.log('Async: Copying to clipboard was successful!');
  }, function(err) {
    console.error('Async: Could not copy text: ', err);
  });
}

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');
});
<div style="display:inline-block; vertical-align:top;">
  <button class="js-copy-bob-btn">Set clipboard to BOB</button><br /><br />
  <button class="js-copy-jane-btn">Set clipboard to JANE</button>
</div>
<div style="display:inline-block;">
  <textarea class="js-test-textarea" cols="35" rows="4">Try pasting into here to see what you have on your clipboard:

  </textarea>
</div>

(codepen.io 示例可能不起作用,请阅读上面的“重要”注释)请注意,此代码段在 Stack Overflow 的嵌入式预览中效果不佳,您可以在此处尝试:https ://codepen.io/DeanMarkTaylor/pen/RMRaJX?editors =1011

异步剪贴板 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 的细微差别和细节。

浏览器支持

JavaScriptdocument.execCommand('copy')支持已增加,请参阅以下链接了解浏览器更新:已弃用

简单示例

(可能无法嵌入本网站,请阅读上面的“重要”说明)

var copyTextareaBtn = document.querySelector('.js-textareacopybtn');

copyTextareaBtn.addEventListener('click', function(event) {
  var copyTextarea = document.querySelector('.js-copytextarea');
  copyTextarea.focus();
  copyTextarea.select();

  try {
    var successful = document.execCommand('copy');
    var msg = successful ? 'successful' : 'unsuccessful';
    console.log('Copying text command was ' + msg);
  } catch (err) {
    console.log('Oops, unable to copy');
  }
});
<p>
  <button class="js-textareacopybtn" style="vertical-align:top;">Copy Textarea</button>
  <textarea class="js-copytextarea">Hello I'm some text</textarea>
</p>

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

textarea如果屏幕上有一个或input元素可见,上面的简单示例效果很好。

在某些情况下,您可能希望将文本复制到剪贴板而不显示input/textarea元素。这是解决此问题的方法的一个示例(基本上是插入元素,复制到剪贴板,删除元素):

使用 Google Chrome 44、Firefox 42.0a1 和 Internet Explorer 11.0.8600.17814 进行测试。

(可能无法嵌入本网站,请阅读上面的“重要”说明)

function copyTextToClipboard(text) {
  var textArea = document.createElement("textarea");

  //
  // *** This styling is an extra step which is likely not required. ***
  //
  // Why is it here? To ensure:
  // 1. the element is able to have focus and selection.
  // 2. if the element was to flash render it has minimal visual impact.
  // 3. less flakyness with selection and copying which **might** occur if
  //    the textarea element is not visible.
  //
  // The likelihood is the element won't even render, not even a
  // flash, so some of these are just precautions. However in
  // Internet Explorer the element is visible whilst the popup
  // box asking the user for permission for the web page to
  // copy to the clipboard.
  //

  // Place in the top-left corner of screen regardless of scroll position.
  textArea.style.position = 'fixed';
  textArea.style.top = 0;
  textArea.style.left = 0;

  // Ensure it has a small width and height. Setting to 1px / 1em
  // doesn't work as this gives a negative w/h on some browsers.
  textArea.style.width = '2em';
  textArea.style.height = '2em';

  // We don't need padding, reducing the size if it does flash render.
  textArea.style.padding = 0;

  // Clean up any borders.
  textArea.style.border = 'none';
  textArea.style.outline = 'none';
  textArea.style.boxShadow = 'none';

  // Avoid flash of the white box if rendered for any reason.
  textArea.style.background = 'transparent';


  textArea.value = text;

  document.body.appendChild(textArea);
  textArea.focus();
  textArea.select();

  try {
    var successful = document.execCommand('copy');
    var msg = successful ? 'successful' : 'unsuccessful';
    console.log('Copying text command was ' + msg);
  } catch (err) {
    console.log('Oops, unable to copy');
  }

  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');
});
<div style="display:inline-block; vertical-align:top;">
  <button class="js-copy-bob-btn">Set clipboard to BOB</button><br /><br />
  <button class="js-copy-jane-btn">Set clipboard to JANE</button>
</div>
<div style="display:inline-block;">
  <textarea class="js-test-textarea" cols="35" rows="4">Try pasting into here to see what you have on your clipboard:

  </textarea>
</div>

补充笔记

仅当用户采取行动时才有效

所有document.execCommand('copy')调用都必须是用户操作的直接结果,例如单击事件处理程序。这是一种防止在用户不期望的情况下弄乱用户剪贴板的措施。

有关详细信息,请参阅此处的 Google Developers 帖子

剪贴板 API

注意完整的剪贴板 API 草案规范可以在这里找到: https ://w3c.github.io/clipboard-apis/

是否支持?

  • document.queryCommandSupported('copy')true如果命令“浏览器支持”,则应返回。
  • 如果现在调用将成功,则document.queryCommandEnabled('copy')返回。检查以确保从用户启动的线程调用命令并满足其他要求。truedocument.execCommand('copy')

但是,作为浏览器兼容性问题的一个示例,Google Chrome 从 2015 年 4 月到 2015 年 10 月仅在truedocument.queryCommandSupported('copy')用户启动的线程调用命令时才返回。

请注意下面的兼容性详细信息。

浏览器兼容性详情

虽然由于用户单击而对document.execCommand('copy')包装在try/catch块中的简单调用将为您提供最大的兼容性,但使用以下有一些附带条件:

对或document.execCommand的任何调用都应包含在/块中。document.queryCommandSupporteddocument.queryCommandEnabledtrycatch

不同的浏览器实现和浏览器版本在调用而不是返回时会抛出不同类型的异常false

不同的浏览器实现仍在不断变化,剪贴板 API仍在草稿中,因此请记住进行测试。

于 2015-06-12T18:56:18.323 回答
1335

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

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

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

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

<button id="demo" onclick="copyToClipboard(document.getElementById('demo').innerHTML)">This is what I want to copy</button>

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

于 2011-05-19T08:06:06.560 回答
459

以下方法适用于 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/

于 2015-11-26T00:03:49.120 回答
156

这是我对那个的看法...

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:请注意,使用 htmlinput字段不会尊重换行符\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;
}
于 2017-09-14T09:20:33.823 回答
93

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

    <script type="text/javascript">
        function select_all(obj) {
            var text_val=eval(obj);
            text_val.focus();
            text_val.select();
            r = text_val.createTextRange();
            if (!r.execCommand) return; // feature detection
            r.execCommand('copy');
        }
    </script>
    <input value="http://www.sajithmr.com"
     onclick="select_all(this)" name="url" type="text" />

于 2008-12-30T13:33:45.303 回答
88

如果您想要一个非常简单的解决方案(集成时间不到 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}颜色替换。

于 2010-10-17T14:40:35.000 回答
77

我最近写了一篇关于这个问题的技术博客文章(我在 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 扩展程序,该扩展程序将为您提供剪贴板权限(这是我们为 Lucidchart 所做的)。然后对于安装了您的扩展程序的用户,您只需要自己触发系统事件:

document.execCommand('copy');

看起来 Firefox 有一些选项允许用户授予某些网站访问剪贴板的权限,但我个人没有尝试过这些。

于 2014-12-03T20:31:06.940 回答
73

我喜欢这一个:

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

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

于 2013-04-23T22:32:03.287 回答
58

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 上

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

于 2015-08-11T15:33:37.223 回答
42

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

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

取消阻止剪贴板访问

于 2018-08-06T13:42:39.387 回答
41

我非常成功地使用了它(没有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 中)。

于 2018-07-01T18:52:46.070 回答
35

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

于 2013-11-21T20:41:25.003 回答
29

由于 Chrome 42+ 和 Firefox 41+ 现在支持document.execCommand('copy')命令,因此我结合使用Tim Down 的旧答案Google Developer 的答案,创建了几个用于跨浏览器复制到剪贴板功能的函数:

function selectElementContents(el) {
    // Copy textarea, pre, div, etc.
    if (document.body.createTextRange) {
        // Internet Explorer
        var textRange = document.body.createTextRange();
        textRange.moveToElementText(el);
        textRange.select();
        textRange.execCommand("Copy");
    }
    else if (window.getSelection && document.createRange) {
        // Non-Internet Explorer
        var range = document.createRange();
        range.selectNodeContents(el);
        var sel = window.getSelection();
        sel.removeAllRanges();
        sel.addRange(range);
        try {
            var successful = document.execCommand('copy');
            var msg = successful ? 'successful' : 'unsuccessful';
            console.log('Copy command was ' + msg);
        }
        catch (err) {
            console.log('Oops, unable to copy');
        }
    }
} // end function selectElementContents(el)

function make_copy_button(el) {
    var copy_btn = document.createElement('input');
    copy_btn.type = "button";
    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) {
        // Copy works with Internet Explorer 4+, Chrome 42+, Firefox 41+, Opera 29+
        copy_btn.value = "Copy to Clipboard";
    }
    else {
        // Select only for Safari and older Chrome, Firefox and Opera
        copy_btn.value = "Select All (then press Ctrl + C to Copy)";
    }
}
/* Note: document.queryCommandSupported("copy") should return "true" on browsers that support copy,
    but there was a bug in Chrome versions 42 to 47 that makes it return "false".  So in those
    versions of Chrome feature detection does not work!
    See https://code.google.com/p/chromium/issues/detail?id=476508
*/

make_copy_button(document.getElementById("markup"));
<pre id="markup">
  Text that can be copied or selected with cross browser support.
</pre>

于 2015-11-05T03:50:33.120 回答
28

    $("td").click(function (e) {
        var clickedCell = $(e.target).closest("td");
        navigator.clipboard.writeText(clickedCell.text());
        alert(clickedCell.text());
    });
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr>
<td>First<td>
</tr>
<tr>
<td>Second<td>
</tr>
<tr>
<td>Third<td>
</tr>
<tr>
<td>Fourth<td>
</tr>
</table>

我已经阅读了所有答案,截至 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

于 2020-06-01T08:48:01.380 回答
27

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

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

于 2011-05-03T22:17:01.680 回答
25

我找到了以下解决方案:

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。

于 2012-07-05T15:33:32.850 回答
25

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

  • 使用 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')

于 2017-07-25T15:51:33.473 回答
24

其他方法会将纯文本复制到剪贴板。要复制 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();
于 2008-12-30T14:33:38.287 回答
17

此代码在 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>
于 2021-05-20T10:59:51.480 回答
14

从 Flash 10 开始,如果操作源自用户与 Flash 对象的交互,则只能复制到剪贴板。(阅读 Adob​​e 的 Flash 10 公告中的相关部分。)

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

于 2010-03-17T20:12:39.990 回答
13

已经有很多答案,但是想添加一个(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.');
}
于 2016-12-12T16:22:02.410 回答
13

我找到了以下解决方案:

我在隐藏输入中有文本。因为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;
}
于 2017-01-18T10:57:02.620 回答
12

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

 function myFunction() {
   /* Get the text field */
   var copyText = document.getElementById("myInput");

   /* Select the text field */
   copyText.select();

   /* Copy the text inside the text field */
   document.execCommand("Copy");

   /* Alert the copied text */
   alert("Copied the text: " + copyText.value);
 }
 <!-- The text field -->
 <input type="text" value="Hello Friend" id="myInput">

 <!-- The button used to copy the text -->
<button onclick="myFunction()">Copy text</button>

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

来源W3Schools -将文本复制到剪贴板

于 2018-01-25T22:42:01.973 回答
12

复制文本字段内文本的最佳方法。使用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>
于 2021-12-19T18:10:03.897 回答
10

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

于 2008-12-30T13:38:51.957 回答
10

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

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

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

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

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

于 2011-01-17T17:09:45.453 回答
10

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

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"/>' )
于 2015-07-09T14:24:25.117 回答
9
function copytoclipboard(element) {

    var $temp = $("<input>");
    $("body").append($temp);
    $temp.val('0' + element).select();
    document.execCommand("copy");
    $temp.remove();
}
于 2019-11-11T18:51:43.227 回答
8

这是Chase Seibert 答案的扩展,其优点是它适用于 IMAGE 和 TABLE 元素,而不仅仅是 Internet Explorer 9 上的 DIV。

if (document.createRange) {
    // Internet Explorer 9 and modern browsers
    var r = document.createRange();
    r.setStartBefore(to_copy);
    r.setEndAfter(to_copy);
    r.selectNode(to_copy);
    var sel = window.getSelection();
    sel.addRange(r);
    document.execCommand('Copy');  // Does nothing on Firefox
} else {
    // Internet Explorer 8 and earlier. This stuff won't work
    // on Internet Explorer 9.
    // (unless forced into a backward compatibility mode,
    // or selecting plain divs, not img or table).
    var r = document.body.createTextRange();
    r.moveToElementText(to_copy);
    r.select()
    r.execCommand('Copy');
}
于 2011-08-12T08:17:32.383 回答
8

我用过剪贴板.js。

我们可以在 npm 上获取它:

npm install clipboard --save

还有在鲍尔

bower install clipboard --save

new ClipboardJS("#btn1");

document.querySelector("#btn2").addEventListener("click", () => document.querySelector("#btn1").dataset.clipboardText = Math.random());
<script src="https://cdn.jsdelivr.net/npm/clipboard@2.0.8/dist/clipboard.min.js"></script>

<button id="btn1" data-clipboard-text="Text to copy goes here">
    Copy to clipboard
</button>
<button id="btn2">Click here to change data-clipboard-text</button>

<br /><br />

<input type="text" placeholder="Paste here to see clipboard" />

更多用法和示例位于https://zenorocha.github.io/clipboard.js/

于 2015-10-28T11:17:06.240 回答
8

要将选定的文本(“要复制的文本”)复制到剪贴板,请创建一个 Bookmarklet(执行 JavaScript 的浏览器书签)并执行它(单击它)。它将创建一个临时文本区域。

来自 GitHub 的代码:

https://gist.github.com/stefanmaric/2abf96c740191cda3bc7a8b0fc905a7d

(function (text) {
  var node = document.createElement('textarea');
  var selection = document.getSelection();

  node.textContent = text;
  document.body.appendChild(node);

  selection.removeAllRanges();
  node.select();
  document.execCommand('copy');

  selection.removeAllRanges();
  document.body.removeChild(node);
})('Text To Copy');
于 2017-10-19T02:33:37.960 回答
6

似乎我误读了这个问题,但作为参考,您可以提取 DOM 的范围(而不是剪贴板;与所有现代浏览器兼容),并将其与 oncopy、onpaste 和 onbeforepaste 事件结合以获取剪贴板行为。这是实现此目的的代码:

function clipBoard(sCommand) {
  var oRange = contentDocument.createRange();
  oRange.setStart(startNode, startOffset);
  oRange.setEnd(endNode, endOffset);

  /* This is where the actual selection happens.
     in the above, startNode and endNode are
     DOM nodes defining the beginning and
     end of the "selection" respectively.

     startOffset and endOffset are constants
     that are defined as follows:

         END_TO_END: 2
         END_TO_START: 3
         NODE_AFTER: 1
         NODE_BEFORE: 0
         NODE_BEFORE_AND_AFTER: 2
         NODE_INSIDE: 3
         START_TO_END: 1
         START_TO_START: 0

     And it would be used like oRange.START_TO_END
  */

  switch(sCommand) {

    case "cut":
      this.oFragment = oRange.extractContents();
      oRange.collapse();
      break;

    case "copy":
      this.oFragment = oRange.cloneContents();
      break;

    case "paste":
      oRange.deleteContents();
      var cloneFragment = this.oFragment.cloneNode(true)
      oRange.insertNode(cloneFragment);
      oRange.collapse();
      break;
  }
}
于 2011-08-16T19:22:47.043 回答
6

我的错。这仅适用于 Internet Explorer。

这是另一种复制文本的方法:

<p>
    <a onclick="window.clipboardData.setData('text', document.getElementById('Test').innerText);">Copy</a>
</p>
于 2013-09-13T21:56:09.130 回答
6

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

navigator.clipboard.writeText(textExample);

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

于 2022-01-29T13:45:39.867 回答
5

据我所知,这只适用于 Internet Explorer。

另请参阅Dynamic Tools - JavaScript Copy To Clipboard,但它需要用户先更改配置,即使那样它似乎也不起作用。

于 2008-12-30T13:26:42.183 回答
5

看起来您从Greasemonkey\JavaScript 复制到剪贴板按钮或此代码段的原始来源中获取了代码...

此代码用于 Greasemonkey,因此是 unsafeWindow。我猜 Internet Explorer 中的语法错误来自constFirefox 特有的关键字(将其替换为var)。

于 2008-12-30T14:47:36.013 回答
5

这是我在互联网上查找各种方法后唯一开始工作的事情。这是一个混乱的话题。世界各地发布了许多解决方案,但其中大多数都不起作用。这对我有用:

注意:此代码仅在作为类似“onClick”方法的直接同步代码执行时才有效。如果您调用对 Ajax 的异步响应或以任何其他异步方式,它将不起作用。

copyToClipboard(text) {
    var copyText = document.createElement("input");
    copyText.type = "text";
    document.body.appendChild(copyText);
    copyText.style = "display: inline; width: 1px;";
    copyText.value = text;
    copyText.focus();
    document.execCommand("SelectAll");
    document.execCommand("Copy");
    copyText.remove();
}

我确实意识到这段代码会在屏幕上显示一个 1 像素宽的组件,持续一毫秒,但我决定不用担心,如果真的有问题,其他人可以解决这个问题。

于 2017-10-14T23:15:10.663 回答
5

尝试使用此功能


const copyToClipboard = (
  value,
  successfully = () => null,
  failure = () => null
) => {
  const clipboard = navigator.clipboard;
  if (clipboard !== undefined && clipboard !== "undefined") {
    navigator.clipboard.writeText(value).then(successfully, failure);
  } else {
    if (document.execCommand) {
      const el = document.createElement("input");
      el.value = value;
      document.body.append(el);

      el.select();
      el.setSelectionRange(0, value.length);

      if (document.execCommand("copy")) {
        successfully();
      }

      el.remove();
    } else {
      failure();
    }
  }
};
于 2021-10-21T08:18:14.687 回答
4

这是同一网站的简单的基于 Ajax/会话的剪贴板。

请注意,会话必须启用且有效,并且此解决方案适用于同一站点。我在 CodeIgniter 上对其进行了测试,但遇到了 session/Ajax 问题,但这解决了这个问题。如果您不想玩会话,请使用数据库表。

JavaScript/jQuery

<script type="text/javascript">
    $(document).ready(function() {

        $("#copy_btn_id").click(function(){

            $.post("<?php echo base_url();?>ajax/foo_copy/"+$(this).val(), null,
                function(data){
                    // Copied successfully
                }, "html"
            );
        });

        $("#paste_btn_id").click(function() {

           $.post("<?php echo base_url();?>ajax/foo_paste/", null,
               function(data) {
                   $('#paste_btn_id').val(data);
               }, "html"
           );
        });
    });
</script>

HTML 内容

<input type='text' id='copy_btn_id' onclick='this.select();'  value='myvalue' />
<input type='text' id='paste_btn_id' value='' />

PHP 代码

<?php
    class Ajax extends CI_Controller {

        public function foo_copy($val){
            $this->session->set_userdata(array('clipboard_val' => $val));
        }

        public function foo_paste(){
            echo $this->session->userdata('clipboard_val');
            exit();
        }
    }
?>
于 2013-08-06T12:10:24.597 回答
4

我不得不从页面中复制非输入框文本(任何 div/span 标签内的文本)并提出以下代码。唯一的诀窍是有一个隐藏字段,但作为 TEXT 类型。它不适用于隐藏类型。

function copyToClipboard(sID) {
    var aField = document.getElementById("hiddenField");

    aField.hidden = false;
    aField.value  = document.getElementById(sID).textContent;
    aField.select();
    document.execCommand("copy");
    alert("Following text has been copied to the clipboard.\n\n" + aField.value);
    aField.hidden = true;
}

并在 HTML 中添加以下内容:

input type="text" id="hiddenField" style="width:5px;border:0" />
...
于 2017-01-09T02:22:17.233 回答
4

Stackoverflow 的解决方案

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

在此处输入图像描述

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

在此处输入图像描述

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

于 2022-01-20T15:26:27.433 回答
3

如果必须将复制的链接粘贴到同一站点上,那么一个简单的解决方案是在按下简单的 HTML 复制按钮之前突出显示文本,然后按下它,文本内容将存储在会话中。在要粘贴的地方,都有一个粘贴按钮。

**我知道,这不是一个持久和通用的解决方案,但它是 :)

于 2013-06-26T07:28:21.147 回答
3

如果您在 Chrome 扩展程序中从剪贴板读取文本,并且允许“clipboardRead”权限,您可以使用以下代码:

function readTextFromClipboardInChromeExtension() {
    var ta = $('<textarea/>');
    $('body').append(ta);
    ta.focus();
    document.execCommand('paste');
    var text = ta.val();
    ta.blur();
    ta.remove();
    return text;
}
于 2013-10-21T11:39:39.470 回答
3

除了Dean Taylor 的更新答案(2015 年 7 月),我还写了一个 jQuery 方法,看起来像他的示例。

jsFiddle

/**
* Copies the current selected text to the SO clipboard
* This method must be called from an event to work with `execCommand()`
* @param {String} text Text to copy
* @param {Boolean} [fallback] Set to true shows a prompt
* @return Boolean Returns `true` if the text was copied or the user clicked on accept (in prompt), `false` otherwise
*/
var CopyToClipboard = function(text, fallback){
    var fb = function () {
        $t.remove();
        if (fallback !== undefined && fallback) {
            var fs = 'Please, copy the following text:';
            if (window.prompt(fs, text) !== null) return true;
        }
        return false;
    };
    var $t = $('<textarea />');
    $t.val(text).css({
        width: '100px',
        height: '40px'
    }).appendTo('body');
    $t.select();
    try {
        if (document.execCommand('copy')) {
            $t.remove();
            return true;
        }
        fb();
    }
    catch (e) {
        fb();
    }
};
于 2015-09-08T11:51:52.533 回答
3

2015 年更新:目前有一种使用document.execCommand剪贴板的方法。

clipboard.js提供了一种使用剪贴板的跨浏览器方式(浏览器支持)。

于 2015-10-05T09:29:10.970 回答
3

在这里找到了这个解决方案。document.execCommand("copy");Internet Explorer 8 和更早版本不支持 。

const copyBtn =  document.getElementById("copyBtn");
const input = document.getElementById("input");

function copyText() {
  const value = input.value;
  
  input.select(); // selects the input variable as the text to be copied
  input.setSelectionRange(0, 99999); // this is used to set the selection range for mobile devices
  
  document.execCommand("copy"); // copies the selected text
  
  alert("Copied the text " + value); // displays the copied text in a prompt
}

copyBtn.onmousedown = function () {
  copyText();
}
<input type="text" id="input" placeholder="Type text to copy... "/>
<button id="copyBtn">
  Copy
</button>

于 2020-11-04T21:20:34.067 回答
3

简单、即用型且不会过时的解决方案:

function copyToClipboard(elementIdToCopy, elementIdToNotifyOutcome) {
    const contentToCopy = document.getElementById(elementIdToCopy).innerHTML;
    const elementToNotifyOutcome = document.getElementById(elementIdToNotifyOutcome);

    navigator.clipboard.writeText(contentToCopy).then(function() {
        elementToNotifyOutcome.classList.add('success');
        elementToNotifyOutcome.innerHTML = 'Copied!';
    }, function() {
        elementToNotifyOutcome.classList.add('failure');
        elementToNotifyOutcome.innerHTML = 'Sorry, did not work.';
    });
}
于 2020-12-09T21:33:54.450 回答
2

在 Chrome 中,您可以使用copy('the text or variable etc'). 虽然这不是跨浏览器(并且不能在片段中工作?),但您可以将其添加到其他跨浏览器答案中。

于 2014-07-02T14:28:28.423 回答
2

我打算使用clipboard.js,但它没有任何移动解决方案(还)......所以我写了一个超级小库:

雪佛兰

这将复制文本(桌面、Android 和 Safari 10+),或者至少选择文本(旧版本的 iOS)。缩小它刚刚超过 1 kB。在桌面 Safari(版本 10 之前)中,它告诉用户"Press Command + C to copy"。您也无需编写任何 JavaScript 即可使用它。

于 2015-10-10T04:13:00.630 回答
2

我在一个简单的解决方案中编译了一些函数来涵盖所有情况,如果需要,可以及时回退。

window.copyToClipboard = function(text) {
  // Internet Explorer specific
  if (window.clipboardData && window.clipboardData.setData) {
    return clipboardData.setData("Text", text);
  }

  // All other modern browsers
  target = document.createElement("textarea");
  target.style.position = "absolute";
  target.style.left = "-9999px";
  target.style.top = "0";
  target.textContent = text;
  document.body.appendChild(target);
  target.focus();
  target.setSelectionRange(0, target.value.length);

  // Copy the selection of fall back to prompt
  try {
    document.execCommand("copy");
    target.remove();
    console.log('Copied to clipboard: "'+text+'"');
  }
  catch(e) {
    console.log("Can't copy string on this browser. Try to use Chrome, Firefox or Opera.")
    window.prompt("Copy to clipboard: Ctrl+C, Enter", text);
  }
}

在这里测试它:https ://jsfiddle.net/jv0avz65/

于 2017-07-13T11:16:47.820 回答
2

这是唯一对我有用的东西:

let textarea = document.createElement('textarea');
textarea.setAttribute('type', 'hidden');
textarea.textContent = 'the string you want to copy';
document.body.appendChild(textarea);
textarea.select();
document.execCommand('copy');
于 2018-01-11T21:07:28.053 回答
2

使用 JavaScript 功能try/catch甚至可以更好地处理错误,如下所示:

copyToClipboard() {
    let el = document.getElementById('Test').innerText
    el.focus(); // el.select();
    try {
        var successful = document.execCommand('copy');
        if (successful) {
            console.log('Copied Successfully! Do whatever you want next');
        }
        else {
            throw ('Unable to copy');
        }
    }
    catch (err) {
        console.warn('Oops, Something went wrong ', err);
    }
}
于 2018-01-19T16:30:29.043 回答
2

使用document.execCommand将为您完成工作...

使用它,您还可以进行剪切复制粘贴...

这是一种简单的剪贴板复制功能,可以复制输入文本中的所有内容...

function copyInputText() {
  var copyText = document.querySelector("#input");
  copyText.select();
  document.execCommand("copy");
}

document.querySelector("#copy").addEventListener("click", copyInputText);
<input id="input" type="text" />
<button id="copy">Copy</button>

有关详细信息,请参阅与剪贴板交互(附加组件)。

于 2019-01-26T13:23:09.270 回答
2

textarea这是一个独立的类,通过将其放置在屏幕外,确保不会从临时发生闪烁。

这适用于 Safari(桌面)、Firefox 和 Chrome。

// ================================================================================
// ClipboardClass
// ================================================================================
var ClipboardClass = (function() {

    function copyText(text) {
        // Create a temporary element off-screen to hold text.
        var tempElem = $('<textarea style="position: absolute; top: -8888px; left: -8888px">');
        $("body").append(tempElem);

        tempElem.val(text).select();
        document.execCommand("copy");
        tempElem.remove();
    }


    // ============================================================================
    // Class API
    // ============================================================================
    return {
        copyText: copyText
    };

})();
于 2019-10-30T21:00:29.500 回答
2

以下函数可用于复制到剪贴板:

copyToclipboard = (event, text) => {
    var container = event.currentTarget;
    let tempInnerHtml = container.innerHTML;
    container.innerHTML = text;
    window.getSelection().removeAllRanges();
    let range = document.createRange();
    range.selectNode(container);
    window.getSelection().addRange(range);
    document.execCommand('copy');
    window.getSelection().removeAllRanges();
    container.innerHTML = tempInnerHtml;
}
于 2020-12-16T12:40:28.467 回答
2

添加到 Dean Taylor 的答案,这里有一个简短的答案和一个长答案,因此您可以复制适合您需要的功能:

简短的回答:

只需使用navigator.clipboard.writeText(str)

请参阅caniuse.com 上的剪贴板 API

长答案:

    // Copies a string to clipboard
    // Uses navigator API if available, else uses execCommand (deprecated)
    // Returns a boolean if copy was successful
    // See: https://stackoverflow.com/q/400212/4907950
        async function copyText(str) {
        console.log('Copying', str);
        if (!navigator.clipboard) {
            // fallback
            let input = document.createElement('textarea');
            input.innerHTML = str;
            document.body.appendChild(input);
            input.focus();
            input.select();
            let result;

            try {
                result = document.execCommand('copy');
                console.log(
                    'Fallback: Copying text command was ' + (result ? 'successful' : 'unsuccessful')
                );
            } catch (err) {
                console.error('Fallback: Could not copy text: ', err);
            }
            document.body.removeChild(input);
            return result;
        }
        const result = navigator.clipboard.writeText(str).then(
            function () {
                console.log('Async: Copying to clipboard was successful');
                return true;
            },
            function (err) {
                console.error('Async: Could not copy text: ', err);
                return false;
            }
        );
        return result;
于 2021-10-18T00:39:23.073 回答
1

出于安全原因,您不能这样做。您必须选择 Flash 才能复制到剪贴板。

我建议这个:http: //zeroclipboard.org/

于 2015-05-07T12:36:18.500 回答
1

搜索支持 Safari 和其他浏览器(Internet Explorer 9 及更高版本)的解决方案后,

我使用和 GitHub 一样的:ZeroClipboard

例子:

http://zeroclipboard.org/index-v1.x.html

HTML

<html>
  <body>
    <button id="copy-button" data-clipboard-text="Copy Me!" title="Click to copy me.">Copy to Clipboard</button>
    <script src="ZeroClipboard.js"></script>
    <script src="main.js"></script>
  </body>
</html>

JavaScript

var client = new ZeroClipboard(document.getElementById("copy-button"));

client.on("ready", function (readyEvent) {
    // alert( "ZeroClipboard SWF is ready!" );

    client.on("aftercopy", function (event) {
        // `this` === `client`
        // `event.target` === the element that was clicked
        event.target.style.display = "none";
        alert("Copied text to clipboard: " + event.data["text/plain"]);
    });
});
于 2016-05-25T15:06:19.373 回答
1

这是最好的。赢了这么多。

var toClipboard = function(text) {
    var doc = document;

    // Create temporary element
    var textarea = doc.createElement('textarea');
    textarea.style.position = 'absolute';
    textarea.style.opacity  = '0';
    textarea.textContent    = text;

    doc.body.appendChild(textarea);

    textarea.focus();
    textarea.setSelectionRange(0, textarea.value.length);

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

    textarea.remove();

    return success;
}
于 2017-09-01T15:20:30.587 回答
1

这是一个简单的例子;)

<!DOCTYPE html>
<html>
    <body>
        <input type="text"
               value="Hello, World!"
               id="myInput">
        <button onclick="myFunction()">Copy text</button>

        <p>The document.execCommand() method is not supported
           in Internet&nbsp;Explorer&nbsp;8 and earlier.</p>

        <script>
            function myFunction() {
                var copyText = document.getElementById("myInput");
                copyText.select();
                document.execCommand("copy");
                alert("Copied the text: " + copyText.value);
            }
        </script>
    </body>
</html>
于 2019-08-19T08:43:44.310 回答
1
document.querySelector('#some_your_textfield_id').select();
document.execCommand('copy');

第一行是选择要复制的文本。

第二行是复制选定的文本。

于 2020-10-13T16:16:15.680 回答
0

我已经将@dean-taylor 提出的解决方案与其他地方的一些其他选择/取消选择代码一起放在 NPM 上可用的 jQuery 插件中:

https://www.npmjs.com/package/jquery.text-select

安装:

npm install --save jquery.text-select

用法:

<script>
    $(document).ready(function(){
        $("#selectMe").selectText(); // Hightlight / select the text
        $("#selectMe").selectText(false); // Clear the selection

        $("#copyMe").copyText(); // Copy text to clipboard
    });
</script>

有关方法/事件的更多信息可以在上面的 NPM 注册表页面中找到。

于 2017-07-14T10:46:41.843 回答
0

这是 Angular 5.x+ 的优雅解决方案:

零件:

import {
  ChangeDetectionStrategy,
  ChangeDetectorRef,
  Component,
  ElementRef,
  EventEmitter,
  Input,
  OnInit,
  Output,
  Renderer2,
  ViewChild
} from '@angular/core';

@Component({
  selector: 'copy-to-clipboard',
  templateUrl: './copy-to-clipboard.component.html',
  styleUrls: ['./copy-to-clipboard.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush
})

export class CopyToClipboardComponent implements OnInit {
  @ViewChild('input') input: ElementRef;
  @Input() size = 'md';
  @Input() theme = 'complement';
  @Input() content: string;
  @Output() copied: EventEmitter<string> = new EventEmitter<string>();
  @Output() error: EventEmitter<string> = new EventEmitter<string>();

  constructor(private renderer: Renderer2) {}

  ngOnInit() {}

  copyToClipboard() {

    const rootElement = this.renderer.selectRootElement(this.input.nativeElement);

    // iOS Safari blocks programmtic 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)) {

      this.renderer.setAttribute(this.input.nativeElement, 'contentEditable', 'true');

      const range = document.createRange();

      range.selectNodeContents(this.input.nativeElement);

      const sel = window.getSelection();

      sel.removeAllRanges();
      sel.addRange(range);

      rootElement.setSelectionRange(0, 999999);
    } else {
      rootElement.select();
    }

    try {
      document.execCommand('copy');
      this.copied.emit();
    } catch (err) {
      this.error.emit(err);
    }
  };
}

模板:

<button class="btn btn-{{size}} btn-{{theme}}" type="button" (click)="copyToClipboard()">
  <ng-content></ng-content>
</button>

<input #input class="hidden-input" [ngModel]="content">

款式:

.hidden-input {
  position: fixed;
  top: 0;
  left: 0;
  width: 1px; 
  height: 1px;
  padding: 0;
  border: 0;
  box-shadow: none;
  outline: none;
  background: transparent;
}
于 2018-02-26T12:25:54.707 回答
0

这是我的解决方案:

var codeElement =
    document.getElementsByClassName("testelm") &&
        document.getElementsByClassName("testelm").length ?
    document.getElementsByClassName("testelm")[0] :
    "";
if (codeElement != "") {
    var e = document.createRange();
    e.selectNodeContents(codeElement);
    var selection = window.getSelection();
    selection.removeAllRanges();
    selection.addRange(e);
    document.execCommand("Copy");
    selection.removeAllRanges();
}
于 2018-05-05T10:14:55.367 回答
0

可以通过使用 getElementbyId、Select()、blur() 和复制命令的组合来完成。

笔记

select() 方法选择 <textarea> 元素或带有文本字段的 <input> 元素中的所有文本。这可能不适用于按钮。

用法

let copyText = document.getElementById('input-field');
copyText.select()
document.execCommand("copy");
copyReferal.blur()
document.getElementbyId('help-text').textContent = 'Copied'

blur() 方法将删除难看的突出显示部分,而不是您可以在漂亮的消息中显示您的内容已成功复制

于 2018-11-21T11:12:15.250 回答
0

我尝试了很多解决方案。如果它适用于现代浏览器,则它不适用于 Internet Explorer。如果它在 Internet Explorer 中工作,它不会在 iOS 上。我终于对它们进行了整理,并得出了适用于所有浏览器、iOS、webview 和 Android 的以下修复程序。

注意:我还介绍了用户拒绝剪贴板权限的场景。此外,即使用户手动复制,也会显示“链接已复制”消息。

<div class="form-group col-md-12">
    <div class="input-group col-md-9">
        <input name="copyurl"
               type="text"
               class="form-control br-0 no-focus"
               id="invite-url"
               placeholder="http://www.invitelink.com/example"
               readonly>
        <span class="input-group-addon" id="copy-link" title="Click here to copy the invite link">
            <i class="fa fa-clone txt-18 text-success" aria-hidden="true"></i>
        </span>
    </div>
    <span class="text-success copy-success hidden">Link copied.</span>
</div>

脚本:

var addEvent =  window.attachEvent || window.addEventListener;
var event = 'copy';
var $inviteUrl = $('#invite-url');

$('#copy-link').on('click', function(e) {
    if ($inviteUrl.val()) {
        if (navigator.userAgent.match(/ipad|ipod|iphone/i)) {
            var el = $inviteUrl.get(0);
            var editable = el.contentEditable;
            var readOnly = el.readOnly;
            el.contentEditable = true;
            el.readOnly = false;
            var range = document.createRange();
            range.selectNodeContents(el);
            var sel = window.getSelection();
            sel.removeAllRanges();
            sel.addRange(range);
            el.setSelectionRange(0, 999999);
            el.contentEditable = editable;
            el.readOnly = readOnly;
            document.execCommand('copy');
            $inviteUrl.blur();
        }
        else {
            $inviteUrl.select();
            document.execCommand("copy");
        }
    }
});

addEvent(event, function(event) {
    if ($inviteUrl.val() && event.target.id == 'invite-url') {
        var $copyLink = $('#copy-link i');
        $copyLink.removeClass('fa-clone');
        $copyLink.addClass('fa-check');
        $('.copy-success').removeClass('hidden');
        setTimeout(function() {
            $copyLink.removeClass('fa-check');
            $copyLink.addClass('fa-clone');
            $('.copy-success').addClass('hidden');
        }, 2000);
    }
});
于 2019-08-06T10:31:51.847 回答
-6

这可能是您问题的解决方案

function CopyToNotepad(id){
    var r = document.createRange();
    r.selectNode(document.getElementById(id));
    window.getSelection().removeAllRanges();
    window.getSelection().addRange(r);
    document.execCommand('copy');
    window.getSelection().removeAllRanges();
}

注意:id应该是您要将内容复制到的父元素 id 。例如:假设您要复制列表中的所有内容,则 id 应按如下方式使用:

<ul id="dummy_id">
<li>copy content 1 </li>
<li>copy content 2 </li>
<li>copy content 3 </li>
<li>copy content 4 </li>
<li>copy content 5 </li>
</ul>

那么函数调用应该是这样的

CopyToNotepad(dummy_id)

谢谢。当然这可以解决你的问题!

于 2021-03-24T06:50:11.803 回答