【问题标题】:Copy / Put text on the clipboard with FireFox, Safari and Chrome使用 FireFox、Safari 和 Chrome 在剪贴板上复制/放置文本
【发布时间】:2023-03-21 22:00:01
【问题描述】:

在 Internet Explorer 中,我可以使用 clipboardData 对象访问剪贴板。如何在 FireFox、Safari 和/或 Chrome 中做到这一点?

【问题讨论】:

标签: javascript dom clipboard


【解决方案1】:

出于安全原因,Firefox 不允许您在剪贴板上放置文本。不过,有一个使用 Flash 的解决方法。

function copyIntoClipboard(text) {

    var flashId = 'flashId-HKxmj5';

    /* Replace this with your clipboard.swf location */
    var clipboardSWF = 'http://appengine.bravo9.com/copy-into-clipboard/clipboard.swf';

    if(!document.getElementById(flashId)) {
        var div = document.createElement('div');
        div.id = flashId;
        document.body.appendChild(div);
    }
    document.getElementById(flashId).innerHTML = '';
    var content = '<embed src="' +
        clipboardSWF +
        '" FlashVars="clipboard=' + encodeURIComponent(text) +
        '" width="0" height="0" type="application/x-shockwave-flash"></embed>';
    document.getElementById(flashId).innerHTML = content;
}

唯一的缺点是这需要启用 Flash。

源当前已死:http://bravo9.com/journal/copying-text-into-the-clipboard-with-javascript-in-firefox-safari-ie-opera-292559a2-cc6c-4ebf-9724-d23e8bc5ad8a/(其Google cache也是如此)

【讨论】:

  • 第三个缺点是它不能在本地(file://)工作而不改变闪存的权限。 code.google.com/p/zeroclipboard 是围绕此方法构建的库。
  • @b1naryatr0phy:大多数情况下是正确的,但 HTML5 仍然没有替代 Flash 当前提供的剪贴板功能(例如,使用 ZeroClipboard)。
  • 自 2014 年起,此方法不再适用于任何现代浏览器。 ZeroClipboard 是目前唯一能解决这个问题的技术
  • 截至 2015 年 9 月,Flash 正在以相对较快的速度消亡,ZeroClipboard 是基于它的使用。有关不使用 Flash 的解决方案,请参阅下面我 2015 年 8 月的回答。
【解决方案2】:

Firefox 确实允许您将数据存储在剪贴板中,但出于安全考虑,默认情况下它是禁用的。在 Mozilla Firefox 知识库的"Granting JavaScript access to the clipboard" 中查看如何启用它。

如果您有很多用户并且无法配置他们的浏览器,amdfan 提供的解决方案是最佳选择。如果用户精通技术,您可以测试剪贴板是否可用并提供更改设置的链接。 JavaScript 编辑器TinyMCE 遵循这种方法。

【讨论】:

    【解决方案3】:

    copyIntoClipboard() 函数适用于 Flash 9,但它似乎因 Flash 播放器 10 的发布而被破坏。下面是一个适用于新 Flash 播放器的解决方案:

    http://bowser.macminicolo.net/~jhuckaby/zeroclipboard/

    这是一个复杂的解决方案,但确实有效。

    【讨论】:

    • 它没有损坏。出于安全原因,它已从最新的 API 中删除
    【解决方案4】:

    我不得不说,这些解决方案都真正有效。我已经从接受的答案中尝试了剪贴板解决方案,但它不适用于 Flash Player 10。我也尝试过 ZeroClipboard,有一段时间我对它非常满意。

    我目前在我自己的网站 (http://www.blogtrog.com) 上使用它,但我一直注意到它存在一些奇怪的错误。 ZeroClipboard 的工作方式是在页面元素的顶部放置一个不可见的 flash 对象。我发现如果我的元素移动(例如当用户调整窗口大小并且我将事物正确对齐时),ZeroClipboard flash 对象就会失控并且不再覆盖该对象。我怀疑它可能仍然坐在原来的位置。他们的代码应该阻止这种情况,或者将其重新粘贴到元素上,但它似乎效果不佳。

    所以...在下一个版本的 BlogTrog 中,我想我会效仿我在野外看到的所有其他代码荧光笔,并删除我的“复制到剪贴板”按钮。 :-(

    (我注意到 dp.syntaxhiglighter 的复制到剪贴板现在也坏了。)

    【讨论】:

    • 当功能不得不以安全的名义后退一步时,这很可悲。我真的希望有一个既安全又允许从网页访问剪贴板的解决方案,即使用户必须明确授予它一次或其他的权限。
    • IE默认就是这样
    【解决方案5】:

    在线电子表格应用程序挂钩 Ctrl + CCtrl + V 事件并将焦点转移到隐藏的 TextArea控件并将其内容设置为所需的新剪贴板内容以进行复制或在事件完成后读取其内容以进行粘贴。

    另请参阅Is it possible to read the clipboard in Firefox, Safari and Chrome using JavaScript?

    【讨论】:

      【解决方案6】:

      Flash 解决方案的一个小改进是使用 swfobject 检测 Flash 10:

      http://code.google.com/p/swfobject/

      如果它显示为 Flash 10,请尝试使用 JavaScript 加载 Shockwave 对象。 Shockwave 还可以使用 Lingo 中的 copyToClipboard() 命令读取/写入剪贴板(在所有版本中)。

      【讨论】:

        【解决方案7】:

        http://www.rodsdot.com/ee/cross_browser_clipboard_copy_with_pop_over_message.asp 适用于 Flash 10 和所有支持 Flash 的浏览器。

        ZeroClipboard 也已更新以避免提到的关于页面滚动的错误导致 Flash 电影不再位于正确的位置。

        由于该方法“要求”用户单击按钮进行复制,这对用户来说是一种便利,并且不会发生任何恶意行为。

        【讨论】:

        • 链接(实际上)已损坏:“此域在 NameSilo.com 上免费停放”
        【解决方案8】:

        我使用 GitHub 的 Clippy 来满足我的需要,它是一个简单的基于 Flash 的按钮。如果不需要样式并且对预先在服务器端插入 要粘贴的内容 感到满意,它就可以正常工作。

        【讨论】:

          【解决方案9】:

          尝试创建一个内存全局变量来存储选择。然后另一个函数可以访问变量并进行粘贴。例如,

          var memory = ''; // Outside the functions but within the script tag.
          
          function moz_stringCopy(DOMEle, firstPos, secondPos) {
          
              var copiedString = DOMEle.value.slice(firstPos, secondPos);
              memory = copiedString;
          }
          
          function moz_stringPaste(DOMEle, newpos) {
          
              DOMEle.value = DOMEle.value.slice(0, newpos) + memory + DOMEle.value.slice(newpos);
          }
          

          【讨论】:

          • 可以从其他任何地方复制,而不是单独考虑在页面内
          【解决方案10】:

          查看此链接:

          Granting JavaScript access to the clipboard

          正如大家所说,出于安全原因,默认情况下它是禁用的。上面的页面显示了如何启用它的说明(通过在 Firefox 中编辑 about:configuser.js 文件)。

          幸运的是,有一个名为“AllowClipboardHelper”的插件,只需点击几下即可轻松完成。但是,您仍然需要指导您网站的访问者如何在 Firefox 中启用访问权限。

          【讨论】:

          • 不认为 Chrome/WebKit 有类似的东西吗?
          • 链接似乎已损坏。但它没有坏了,只是非常非常慢......
          【解决方案11】:

          如果你支持Flash,你可以使用https://everyplay.com/assets/clipboard.swf并使用flashvars text来设置文字。

          https://everyplay.com/assets/clipboard.swf?text=It%20Works

          这是我用来复制的,如果它不支持这些选项,您可以设置为额外。您可以使用:

          对于 Internet Explorer:

          window.clipboardData.setData(DataFormat, Text) 和 window.clipboardData.getData(DataFormat)

          您可以使用 DataFormat 的 Text 和 URL 来获取数据和设置数据。

          以及删除数据:

          您可以使用 DataFormat 的文件、HTML、图像、文本和 URL。 PS:你需要使用window.clipboardData.clearData(DataFormat);

          对于不支持 window.clipboardData 和 swf Flash 文件的其他文件,您还可以在 Windows 键盘上使用 Control + C 按钮,对于 Mac 使用其 命令 + C.

          【讨论】:

            【解决方案12】:

            来自插件代码:

            关于如何从 Chrome 代码中执行此操作,您可以使用此处描述的 nsIClipboardHelper 接口:https://developer.mozilla.org/en-US/docs/Using_the_Clipboard

            【讨论】:

            • 链接已损坏:“找不到页面”
            【解决方案13】:

            现在是 2015 年夏天,Flash 周围一片混乱,这里是如何完全避免使用它的方法。

            clipboard.js 是一个不错的实用程序,它允许将文本或 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 也是on GitHub

            【讨论】:

            • 你提供的第一个链接(到 npmjs.com)说它不适用于 IE,但它可以(实际上它在 GitHub 上说)
            【解决方案14】:

            现在有一种方法可以在大多数现代浏览器中使用

            轻松完成此操作
            document.execCommand('copy');
            

            这将复制当前选定的文本。您可以使用

            选择文本区域或输入字段
            document.getElementById('myText').select();
            

            要隐形复制文本,您可以快速生成一个textArea,修改框中的文本,选择它,复制它,然后删除textArea。在大多数情况下,这个 textArea 甚至不会闪现到屏幕上。

            出于安全原因,浏览器仅允许您在用户采取某种操作(即单击按钮)时进行复制。一种方法是将 onClick 事件添加到调用复制文本的方法的 html 按钮。

            一个完整的例子:

            function copier(){
              document.getElementById('myText').select();
              document.execCommand('copy');
            }
            <button onclick="copier()">Copy</button>
            <textarea id="myText">Copy me PLEASE!!!</textarea>

            【讨论】:

              【解决方案15】:

              使用document.execCommand('copy')。最新版本的 Chrome、Firefox、Edge 和 Safari 都支持它。

              function copyText(text){
                function selectElementText(element) {
                  if (document.selection) {
                    var range = document.body.createTextRange();
                    range.moveToElementText(element);
                    range.select();
                  } else if (window.getSelection) {
                    var range = document.createRange();
                    range.selectNode(element);
                    window.getSelection().removeAllRanges();
                    window.getSelection().addRange(range);
                  }
                }
                var element = document.createElement('DIV');
                element.textContent = text;
                document.body.appendChild(element);
                selectElementText(element);
                document.execCommand('copy');
                element.remove();
              }
              
              
              var txt = document.getElementById('txt');
              var btn = document.getElementById('btn');
              btn.addEventListener('click', function(){
                copyText(txt.value);
              })
              <input id="txt" value="Hello World!" />
              <button id="btn">Copy To Clipboard</button>

              【讨论】:

                【解决方案16】:

                使用现代的 document.execCommand("copy") 和 jQuery。见this Stack Overflow answer

                var ClipboardHelper = { // As Object
                
                    copyElement: function ($element)
                    {
                        this.copyText($element.text())
                    },
                    copyText:function(text) // Linebreaks with \n
                    {
                        var $tempInput =  $("<textarea>");
                        $("body").append($tempInput);
                        $tempInput.val(text).select();
                        document.execCommand("copy");
                        $tempInput.remove();
                    }
                };
                

                如何称呼它:

                ClipboardHelper.copyText('Hello\nWorld');
                ClipboardHelper.copyElement($('body h1').first());
                

                // jQuery document
                ;(function ( $, window, document, undefined ) {
                
                    var ClipboardHelper = {
                
                        copyElement: function ($element)
                        {
                           this.copyText($element.text())
                        },
                        copyText:function(text) // Linebreaks with \n
                        {
                            var $tempInput =  $("<textarea>");
                            $("body").append($tempInput);
                
                            //todo prepare Text: remove double whitespaces, trim
                
                            $tempInput.val(text).select();
                            document.execCommand("copy");
                            $tempInput.remove();
                        }
                    };
                
                    $(document).ready(function()
                    {
                        var $body = $('body');
                
                        $body.on('click', '*[data-copy-text-to-clipboard]', function(event)
                        {
                            var $btn = $(this);
                            var text = $btn.attr('data-copy-text-to-clipboard');
                            ClipboardHelper.copyText(text);
                        });
                
                        $body.on('click', '.js-copy-element-to-clipboard', function(event)
                        {
                            ClipboardHelper.copyElement($(this));
                        });
                    });
                })( jQuery, window, document );
                <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
                
                <span data-copy-text-to-clipboard=
                    "Hello
                     World">
                    Copy Text
                </span>
                
                <br><br>
                <span class="js-copy-element-to-clipboard">
                    Hello
                    World
                    Element
                </span>

                【讨论】:

                  【解决方案17】:

                  截至 2017 年,您可以这样做:

                  function copyStringToClipboard (string) {
                      function handler (event){
                          event.clipboardData.setData('text/plain', string);
                          event.preventDefault();
                          document.removeEventListener('copy', handler, true);
                      }
                  
                      document.addEventListener('copy', handler, true);
                      document.execCommand('copy');
                  }
                  

                  现在复制copyStringToClipboard('Hello, World!')

                  如果您注意到setData 这一行,并想知道是否可以设置不同的数据类型,答案是肯定的。

                  【讨论】:

                  • 对于 safari,我需要在输入框上运行 .select(),然后再调用它。
                  • 是否也应该删除事件监听器?
                  • @ChrisWalsh 是的,它是在代码示例的处理程序内部完成的。原因是处理程序仍然在内存中。
                  【解决方案18】:

                  Clipboard API 旨在取代 document.execCommand。 Safari 仍在努力提供支持,因此您应该在规范确定和 Safari 完成实施之前提供回退。

                  const permalink = document.querySelector('[rel="bookmark"]');
                  const output = document.querySelector('output');
                  permalink.onclick = evt => {
                    evt.preventDefault();
                    window.navigator.clipboard.writeText(
                      permalink.href
                    ).then(() => {
                      output.textContent = 'Copied';
                    }, () => {
                      output.textContent = 'Not copied';
                    });
                  };
                  <a href="https://stackoverflow.com/questions/127040/" rel="bookmark">Permalink</a>
                  <output></output>

                  出于安全原因,剪贴板Permissions 可能需要从剪贴板读取和写入。如果 sn-p 在 StackOverflow 上不起作用,请在 localhost 或其他受信任的域上试一试。

                  【讨论】:

                    【解决方案19】:

                    以出色的 answer from David from Studio.201 为基础,可在 Safari、Firefox 和 Chrome 中使用。通过将textarea 放置在屏幕外,它还可以确保不会发生闪烁。

                    // ================================================================================
                    // ClipboardClass
                    // ================================================================================
                    var ClipboardClass = (function() {
                    
                        function copyText(text) {
                            // Create temp 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
                        };
                    })();
                    

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 2012-02-03
                      • 2010-09-19
                      • 2015-11-14
                      • 2017-03-02
                      • 1970-01-01
                      • 2012-11-27
                      • 2011-06-01
                      • 1970-01-01
                      相关资源
                      最近更新 更多