如何使用JavaScript复制到剪贴板?

2020/09/13 23:31 · javascript ·  · 0评论

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

我努力了:

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如何访问用户的剪贴板?

总览

有三种主要的浏览器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('copy')

本文的其余部分深入介绍了document.execCommand('copy')API 的细微差别和细节

浏览器支持

对JavaScript的document.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>

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

如果屏幕上显示textareainput元素,则上面的简单示例非常有用。

在某些情况下,您可能希望在不显示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 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 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 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

注意完整的Clipboard API草案规范可以在以下位置找到:https :
//w3c.github.io/clipboard-apis/

支持吗?

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

但是由于浏览器兼容性问题,谷歌Chrome从日〜4月至〜2015年10月才会返回一个例子true,从document.queryCommandSupported('copy')如果命令是由用户发起的线程调用。

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

浏览器兼容性详细信息

尽管通过用户单击而简单地调用document.execCommand('copy')包装在try/ catch块中的调用将使您获得最大的兼容性,但以下使用一些条件:

到任何呼叫document.execCommanddocument.queryCommandSupporteddocument.queryCommandEnabled应该被包裹在一个try/ catch块。

当调用而不是返回时,不同的浏览器实现和浏览器版本会引发不同类型的异常false

各种浏览器实现仍在不断发展,而Clipboard API仍在起草阶段,因此请记住进行测试。

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

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

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

现在,剪贴板复制操作为SAFE,因为用户手动进行了操作(但以非常简单的方式)。当然,可以在所有浏览器中使用。

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

以下方法适用于Chrome,Firefox,Internet Explorer和Edge,以及最新版本的Safari(复制支持已添加到2016年10月发布的版本10中)。

  • 创建一个textarea并将其内容设置为要复制到剪贴板的文本。
  • 将文本区域附加到DOM。
  • 在文本区域中选择文本。
  • 调用document.execCommand(“ copy”)
  • 从dom中删除文本区域。

注意:您不会看到文本区域,因为它是在同一Javascript代码同步调用中添加和删除的。

如果您自己执行此操作,请注意以下事项:

  • 出于安全考虑,只能从事件处理程序(例如click)中调用(就像打开窗口一样)。
  • 第一次更新剪贴板时,Internet Explorer将显示一个权限对话框。
  • Internet Explorer和Edge将在文本区域成为焦点时滚动。
  • execCommand()在某些情况下可能会抛出。
  • 除非使用textarea,否则换行符和制表符可能会被吞下。(大多数文章似乎建议使用div)
  • 显示Internet Explorer对话框时,文本区域将可见,您需要将其隐藏,或使用Internet Explorer特定的剪贴板数据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 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 false;
        }
        finally {
            document.body.removeChild(textarea);
        }
    }
}

https://jsfiddle.net/fx6a6n6x/

这是我对此的看法...

function copy(text) {
    var input = document.createElement('input');
    input.setAttribute('value', text);
    document.body.appendChild(input);
    input.select();
    var result = document.execCommand('copy');
    document.body.removeChild(input);
    return result;
 }

@korayem:请注意,使用html input字段将不遵守换行符,\n并且会将所有文本拼合为一行。

就像@nikksan在评论中提到的那样,使用textarea可以解决以下问题:

function copy(text) {
    var input = document.createElement('textarea');
    input.innerHTML = text;
    document.body.appendChild(input);
    input.select();
    var result = document.execCommand('copy');
    document.body.removeChild(input);
    return result;
}

从网页上读取和修改剪贴板会引发安全性和隐私问题。但是,在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" />

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

我最近写了一篇有关此问题技术博客文章(我在Lucidchart工作,最近我们对剪贴板进行了大修)。

假定您要在系统复制事件(用户按下CtrlC或使用浏览器的菜单)期间执行此操作,将纯文本复制到剪贴板相对简单

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进行操作的方法,这是唯一的跨浏览器方法(据我所知)。

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

这是IE中最简单的方法,您可以随时通过以下方式从JavaScript访问剪贴板数据对象:

window.clipboardData

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

在Chrome中,您可以创建一个Chrome扩展程序,该扩展程序将为您提供剪贴板权限(这是我们对Lucidchart所做的工作)。然后,对于安装了扩展程序的用户,您只需要自己触发系统事件即可:

document.execCommand('copy');

Firefox似乎有一些选项,允许用户向某些站点授予访问剪贴板的权限,但是我个人还没有尝试过这些选项。

我喜欢这一个:

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

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

剪贴板.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上

注意:现在不建议使用。迁移到这里

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

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

也可以对剪贴板进行更多的体操练习。在此处查看更多信息:

解锁剪贴板访问

在我正在从事的项目之一中,一个使用“ 零剪贴板”的jQuery复制到剪贴板插件

如果您是大量的jQuery用户,那么它比原生的Zero Clipboard插件更易于使用。

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

function copyToClp(txt){
    txt = document.createTextNode(txt);
    var m = document;
    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中是)。

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

function selectElementContents(el) {
    // Copy textarea, pre, div, etc.
    if (document.body.createTextRange) {
        // IE
        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>

其他方法会将纯文本复制到剪贴板。要复制HTML(即,您可以将结果粘贴到WSIWYG编辑器中),则可以在IE Only中执行以下操作这从根本上不同于其他方法,因为浏览器实际上是在选择内容。

// 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();   

我发现以下解决方案:

在按下按键时,处理程序会创建“ 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 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('Fail to paste. :(');
     };
   }

用法:

enyby_clip = new EnybyClipboard(); //init 

enyby_clip.copyText('some_text'); // place this in 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;

在粘贴时,它会创建textarea并以相同的方式工作。

PS可能是此解决方案,可用于创建没有Flash的完全跨浏览器解决方案。它适用于FF和Chrome。

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

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

    $("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/zh-CN/docs/Web/API/Clipboard/writeText

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

解决方案是在“复制”按钮上方放置一个Flash对象,或者使用任何可启动复制的元素。零剪贴板目前是使用此实现的最佳库。有经验的Flash开发人员可能只想创建自己的库。

  <!DOCTYPE html>

  <style>
    #t {
      width: 1px
      height: 1px
      border: none
    }
    #t:focus {
      outline: none
    }
  </style>

  <script>
    function copy(text) {
      var t = document.getElementById('t')
      t.innerHTML = text
      t.select()
      try {
        var successful = document.execCommand('copy')
        var msg = successful ? 'successfully' : 'unsuccessfully'
        console.log('text coppied ' + msg)
      } catch (err) {
        console.log('Unable to copy text')
      }
      t.innerHTML = ''
    }
  </script>

  <textarea id=t></textarea>

  <button onclick="copy('hello world')">
    Click me
  </button>

我发现以下解决方案:

我在隐藏输入中输入了文字。由于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;
}

将文本从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- 将文本复制到剪贴板

已经有很多答案,但是喜欢添加一个(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.');
}

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

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"/>' )

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

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

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

因此,当用户点击Ctrl+时,C他/她将获得他/她选择的复制单元格。经过测试后,只是将textarea调整为一个像素(我没有测试它是否可以在display上工作:无)。它在所有浏览器上都能很好地工作,并且对用户透明。

粘贴-您可以这样做(与目标不同)-继续关注文本区域并使用onpaste捕获粘贴事件(在我的项目中,我在单元格中使用文本区域进行编辑)。

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

我已经使用了剪贴板。

我们可以在npm上获得它:

npm install clipboard --save

还有鲍尔

bower install clipboard --save

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

这是@Chase答案的扩展,其优点是它将适用于IMAGE和TABLE元素,而不仅仅是IE9上的DIV。

if (document.createRange) {
    // IE9 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 FF
} else {
    // IE 8 and earlier.  This stuff won't work on IE9.
    // (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');
}

看来我误解了这个问题,但作为参考,您可以提取一定范围的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 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;
  }
}

我的错。这仅在IE中有效。

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

<p>
    <a onclick="window.clipboardData.setData('text', document.getElementById('Test').innerText);">Copy</a>
</p>
本文地址:http://javascript.askforanswer.com/ruheshiyongjavascriptfuzhidaojiantieban.html
文章标签: ,   ,  
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!