Как мне скопировать в буфер обмена в JavaScript?

Каков наилучший способ скопировать текст в буфер обмена? (Мульти-браузер)

Я пытался:

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,

Хороший трюк без вспышки: как Trello получает доступ к буферу обмена пользователя?

74 ответа

В Chrome вы можете использовать copy('the text or variable etc'), Хотя это не кросс-браузер (и не работает во фрагменте?), Вы можете добавить его к другим кросс-браузерным ответам.

В дополнение к ответу Дина Тейлора, вот короткий и длинный ответ, поэтому вы можете просто скопировать функцию, которая соответствует вашим потребностям:

Короткий ответ:

Просто используйте navigator.clipboard.writeText(str)

См. API буфера обмена на caniuse.com

Длинный ответ:

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

это самый простой способ, который я нашел

      <!DOCTYPE html>
<html>
<body>

 <p>Click on the button to copy the text from the text field. Try to paste 
 the text (e.g. ctrl+v) afterwards in a different window, to see the effect. 
 </p>

  <input type="text" value="Hello World" id="myInput">
  <button onclick="myFunction()">Copy text</button>

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

  /* Select the text field */
   copyText.select();
    copyText.setSelectionRange(0, 99999); /* For mobile devices */

   /* Copy the text inside the text field */
   navigator.clipboard.writeText(copyText.value);

   /* Alert the copied text */
    alert("Copied the text: " + copyText.value);
    }

   </script>

    </body>
    </html>

Просто добавляю мой к ответам.

Это лучшее. Так много побед.

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

        // Create temp 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;
}

Вот простой пример;)

<!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>
document.querySelector('#some_your_textfield_id').select();
document.execCommand('copy');

первая строка для выделения текста, который вы хотите скопировать

вторая строка для копирования выделенного текста

После поиска решения, которое поддерживает Safari и другие браузеры (IE9 +),

Я использую так же, как 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>

JS

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"]);
    });
});

Я собрал решение, представленное здесь @dean-taylor, вместе с другим кодом выбора / отмены выбора из другого места в плагине jQuery, доступном в NPM:

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 выше.

Это можно сделать, просто используя комбинацию getElementbyId, Select(), blur() и команды copy.

Заметка

Метод select() выделяет весь текст в элементе или элементе с текстовым полем. Это может не работать на кнопке

использование

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

Метод blur () удалит некрасиво выделенную часть вместо того, что вы можете показать в красивом сообщении, что ваш контент был успешно скопирован

Вот мое решение

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

Вот элегантное решение для 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://stackru.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;
}

Я пробовал много решений. Если он работает в современных браузерах, то не в 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);
    }
});

Примечание: не дубликат этого ответа, поскольку эта библиотека совершенно не связана с этой, которая гораздо более популярна.

Clipboard.js - популярная библиотека (29,5 тыс. Звезд на GitHub, 3,1 млн загрузок в неделю на npm и 704 млн обращений в месяц на jsDelivr) упрощает копирование текста в буфер обмена:

<script src="https://cdn.jsdelivr.net/npm/clipboard@2.0.6/dist/clipboard.min.js"></script>

<!-- Target -->
<input id="foo" value="foo">

<!-- Trigger -->
<button class="btn" data-clipboard-target="#foo">
    <img src="assets/clippy.svg" alt="Copy to clipboard">
</button>

Ссылки:

Это может быть решением вашей проблемы

      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();
}
Другие вопросы по тегам