Javascript复制到Safari上的剪贴板?

时间:2016-10-20 07:07:56

标签: javascript jquery google-chrome firefox safari

这可能是重复的问题,但我没有找到解决方案。

我正在尝试按下按钮时复制文本。它在chrome,mozilla上工作(在windows和mac上工作但在linux上工作)。而且它没有在野生动物园工作。

我使用document.execCommand("copy")命令进行复制。

safari是否支持此命令?

有没有什么方法可以支持所有浏览器?

8 个答案:

答案 0 :(得分:10)

请检查我的解决方案。

适用于Safari(在iPhone 7和iPad上测试过)和其他浏览器。

window.Clipboard = (function(window, document, navigator) {
    var textArea,
        copy;

    function isOS() {
        return navigator.userAgent.match(/ipad|iphone/i);
    }

    function createTextArea(text) {
        textArea = document.createElement('textArea');
        textArea.value = text;
        document.body.appendChild(textArea);
    }

    function selectText() {
        var range,
            selection;

        if (isOS()) {
            range = document.createRange();
            range.selectNodeContents(textArea);
            selection = window.getSelection();
            selection.removeAllRanges();
            selection.addRange(range);
            textArea.setSelectionRange(0, 999999);
        } else {
            textArea.select();
        }
    }

    function copyToClipboard() {        
        document.execCommand('copy');
        document.body.removeChild(textArea);
    }

    copy = function(text) {
        createTextArea(text);
        selectText();
        copyToClipboard();
    };

    return {
        copy: copy
    };
})(window, document, navigator);

// How to use
Clipboard.copy('text to be copied');

https://gist.github.com/rproenca/64781c6a1329b48a455b645d361a9aa3 https://fiddle.jshell.net/k9ejqmqt/1/

希望对你有所帮助。

问候。

答案 1 :(得分:3)

我发现对于safari,需要在document.execCommand()工作之前选择文本。

此外,其他浏览器(deprecated in Chrome)不支持addRange(),这意味着在某些情况下,它无法正确地将选择内容和范围合并在一起。对于用户体验而言,这意味着用户需要在Safari中单击两次才能复制该值。在添加范围之前添加.removeAllRanges()将有助于确保您正在获取副本的正确选择。不清楚您是否仍然需要第二个.removeAllRanges(),但我认为它是安全的。

 copy(id) {
    var configId = document.querySelector(id);
    var range = document.createRange();
    range.selectNode(configId);
    var selection = window.getSelection()
    selection.removeAllRanges();
    selection.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');
    }

    selection.removeAllRanges();
  }

要使用(在同一个类中):

<Button icon="copy" onClick={() => {this.copy(id)}}/>

id 可以是任何html选择器

这在Chrome和Safari中对我有用。

答案 2 :(得分:3)

这个问题四年后,

野生动物园添加了剪贴板API!

您可以在safari上的剪贴板中写入和读取文本以及任意数据(在iOS中,从v13.4版和台式机v13.1起)。

MDN docs about Clipboard 剪贴板接口实现了剪贴板API,如果 用户授予权限-对以下内容的读写访问权限 系统剪贴板。剪贴板API可用于实施剪切, 在Web应用程序中复制和粘贴功能。

这是您实现所需目标的方法:

navigator.clipboard.writeText("YOUR_TEXT").then(function() {

  /* clipboard successfully set */

}, function() {

  /* clipboard write failed */

});

答案 3 :(得分:1)

因为第一个答案在iPhone 10 Safari上对我不起作用,我试图找到另一个解决方案,我找到了一个描述here

基本上它说的是一个非常相似的解决方案,但语法不同:

支持&#34; IE 10 +,Chrome 43 +,Firefox 41+和Opera 29 +&#34;

&#13;
&#13;
var copyEmailBtn = document.querySelector('.js-emailcopybtn');
copyEmailBtn.addEventListener('click', function(event) {
  // Select the email link anchor text  
  var emailLink = document.querySelector('.js-emaillink');
  var range = document.createRange();
  range.selectNode(emailLink);
  window.getSelection().addRange(range);

  try {
    // Now that we've selected the anchor text, execute the copy command  
    var successful = document.execCommand('copy');
    var msg = successful ? 'successful' : 'unsuccessful';
    console.log('Copy email command was ' + msg);
  } catch (err) {
    console.log('Oops, unable to copy');
  }

  // Remove the selections - NOTE: Should use
  // removeRange(range) when it is supported  
  window.getSelection().removeAllRanges();
});
&#13;
body {
  padding: 10px;
}
&#13;
<p>Email me at <a class="js-emaillink" href="mailto:chriscoyier@gmail.com">chriscoyier@gmail.com</a></p>

<p><button class="js-emailcopybtn">Copy Email</button></p>
&#13;
&#13;
&#13;

它还提到了一个名为clipboardjs的lib,看起来很棒。

在我的例子中,这个简单的js代码适用于:

  • iPhone 10 Safari
  • chrome(android / pc(67.0.3396.79))
  • opera(pc(53.0.2907.68))

不幸的是,它不起作用:

  • pc / android Firefox(60.0.1(64位))

在Firefox的情况下,简单的选择和复制就可以了。

element.select();
document.execCommand('copy');

答案 4 :(得分:1)

使用copy事件似乎对我有用。

window.addEventListener('copy', (event) => {
  event.preventDefault();
  event.clipboardData.setData('text/plain', `foo: ${Date.now()}`);
});
click here, press Cmd-C, paste outside the browser

在Chrome 83,Safari 13.1,Firefox 77中进行了测试

答案 5 :(得分:0)

根据CanIUse,iOS上的Safari不支持document.execCommand('copy'),可能是出于安全原因。

答案 6 :(得分:0)

我遇到了同样的问题-原来是由于我正在创建一个临时select元素来复制文本而引起的,这很好,但是我也通过各种方法将其隐藏,罪魁祸首为element.style.width = 0。删除它并使用其他方法隐藏它解决了我的问题。

希望这可以帮助遇到相同问题的任何人。

答案 7 :(得分:0)

最近我偶然发现了同样的问题,并发现了以下内容:

document.execCommand("copy") 现在在 Safari 中运行没有任何问题。

如果您有一个特定的 copy 命令用例,它不仅在 safari 中工作,您可能需要检查的一件事是您的 copy 命令是在 API 回调中运行还是以其他类似的异步方式运行。此外,只有在来自 DOM 事件时才能在 Safari 中进行复制(控制台测试不起作用)。

对我来说,我要复制的文本来自异步调用的响应。我不得不将 API 调用移到 onClick 之外以预取文本,然后仅在单击复制按钮时复制该文本。成功了!

以下代码将在 Safari 中正常运行(鉴于其直接写入 DOM 事件处理程序,如 onClick):

var clipBoardElem = document.createElement("input");
document.body.appendChild(clipBoardElem);
clipBoardElem.value = "text";
clipBoardElem.select();
var successfulCopy = document.execCommand('copy');

完成后,您可以删除临时元素:

document.body.removeChild(clipBoardElem)