如何在HTML5中不使用Flash复制到剪贴板?

40

我希望在HTML5中使用一个无需Flash的复制到剪贴板功能。这可能吗?如何实现?

我尝试使用JavaScript实现复制到剪贴板功能,但它没有起作用:

function Copytoclipboard() {
    var body = document.body,
        range, sel;
    if (document.createRange && window.getSelection) {
        range = document.createRange();
        sel = window.getSelection();
        sel.removeAllRanges();
        try {
            range.selectNodeContents(el);
            sel.addRange(range);
            document.execCommand('Copy');
        } catch (e) {
            range.selectNode(el);
            sel.addRange(range);
            document.execCommand('Copy');
        }
    } else if (body.createTextRange) {
        range = body.createTextRange();
        range.moveToElementText(el);
        range.select();
        range.execCommand('Copy');
    }
}
6个回答

28

13
“不完全支持”是一种说法,而“无法使用”则是另一种说法。Chrome、Safari和Opera都不支持EventConstructor,这似乎是必须的,如果你想复制任何内容到剪贴板的话。 - Martin Thoma
3
但它确实回答了这个问题。用户要求 HTML5。 - Jomar Sevillejo
移动设备上所有不同浏览器的支持怎么样?它们有成千上万个。HTML5更多是炒作和虚假承诺的预测似乎已经成为现实。如果我们在2015年仍然无法使这个简单的微型功能始终如一地工作,那么我们会在这些东西“正常工作”之前全部退休吗?也许插件架构并不是那么糟糕。对于Eclipse来说效果很好。 - User
1
喜欢 HTML Goodies 不包含工作示例的方式。5 星。 - David

25

更新:此解决方案现在适用于所有主要浏览器的当前版本!

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" />
<button id="btn">Copy To Clipboard</button>

注意:尝试使用此解决方案复制空字符串或只包含空格的字符串将不起作用。

备选、简化解决方案

这个备选解决方案已在Chrome、Safari和Firefox中进行了测试。

const txt = document.querySelector('#txt')
const btn = document.querySelector('#btn')

const copy = (text) => {
  const textarea = document.createElement('textarea')
  document.body.appendChild(textarea)
  textarea.value = text
  textarea.select()
  document.execCommand('copy')
  textarea.remove()
}

btn.addEventListener('click', (e) => {
  copy(txt.value)
})
<input id="txt" />
<button id="btn">Copy</button>

注意:该解决方案不会复制空字符串,但会复制空格。

17

它无法工作是因为需要用户交互,例如点击。否则,document.execCommand 将无法工作。你还可以检查一下clipboard.js,它是一个非常简单的库,可以将文本复制到剪贴板而不需要 Flash。


不是相关答案,但是最佳方法。已点赞。 - Omar Tariq

16

将文本插入剪贴板的函数:

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');
}

FYI 这在今天的所有浏览器上都可能有效。对于 IE,可以使用简单的 window.clipboardData.setData("Text", string) - Binyamin
当您想要复制DOM中不可用的文本时,例如错误消息的堆栈跟踪,这是最佳解决方案。 - Tsvetan Ganev
@Petr Žoček,这位先生的想法绝对是天才之举!我很想知道您是在哪里学到这个方法的?在经过一整天的搜索和尝试许多解决方案后,这是我找到的唯一一个保留数据中样式元素而不过滤它们的解决方案。您应该得到金牌奖励! - Bernd Wechner

6
如果您不关心文本字段的内容在复制之前被选中,这是一个适用于Chrome 56和Edge的两行解决方案,但我敢打赌它在其他浏览器中也适用。

function clickListener() {
  document.getElementById('password').select();
  document.execCommand('copy');
}

document.getElementById('copy_btn').addEventListener('click', clickListener);
<input id=password value="test">
<button id=copy_btn>Copy</button>

https://jsfiddle.net/uwd0rm08/


0

您可以使用Clipboard.js添加复制到剪贴板的功能。这个功能不需要Flash,请看一下我使用的代码:

//for copy to clickboard
var els = document.querySelectorAll('pre');
for (var i=0; i < els.length; i++) {
//for CLIPBOARD
var atr = els[i].innerHTML;
    els[i].setAttribute("data-clipboard-text", atr);
 //For SELECT
 var ids = "elementID"+[i]
    els[i].setAttribute("id", ids);
    els[i].setAttribute("onclick","selectText(this.id)");
 
}
    var btns = document.querySelectorAll('pre');
    var clipboard = new ClipboardJS(btns);

    clipboard.on('success', function(e) {
        console.log(e);
  });

    clipboard.on('error', function(e) {
        console.log(e);
    });
 
 //for select
 function selectText(id){
    var sel, range;
    var el = document.getElementById(id); //get element id
    if (window.getSelection && document.createRange) { //Browser compatibility
      sel = window.getSelection();
      if(sel.toString() == ''){ //no text selection
         window.setTimeout(function(){
            range = document.createRange(); //range object
            range.selectNodeContents(el); //sets Range
            sel.removeAllRanges(); //remove all ranges from selection
            sel.addRange(range);//add Range to a Selection.
        },1);
      }
    }else if (document.selection) { //older ie
        sel = document.selection.createRange();
        if(sel.text == ''){ //no text selection
            range = document.body.createTextRange();//Creates TextRange object
            range.moveToElementText(el);//sets Range
            range.select(); //make selection.
        }
    }
}
<pre>I Have To Copy it<pre>
<script src="https://cdn.jsdelivr.net/npm/clipboard@2/dist/clipboard.min.js"></script>

To Know More About Its Usage visit Source :html5 copy to clipboard


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接