Как скопировать в буфер обмена в 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 не определен.

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

Просто любопытно, что вы хотите скопировать в буфер обмена, чего пользователь не может сделать сам?

scunliffe 30.12.2008 19:52

Ничего особенного. Они могут сделать это сами, но я хочу предложить также возможность нажатия кнопки, не беспокоясь о выборе правильной части текста.

Santiago Corredoira 31.12.2008 03:03

Это длинное сообщение в блоге содержит множество способов сделать это: Доступ к системному буферу обмена с помощью JavaScript - Святой Грааль?

Aaron Digulla 21.04.2011 12:26

Это дает браузеру неопределенное исключение в IE, а также в FF

Jagadeesh 22.02.2013 11:43

Если мы можем поместить текст в буфер обмена пользователя, мы можем испортить его буфер обмена.

Frank Fang 11.06.2014 16:15

Это все еще не полностью поддерживается. Вы можете увидеть поддержку на Могу ли я использовать API буфера обмена? в котором подробно описывается поддержка Документ API буфера обмена W3C.

mkobit 29.04.2015 00:47

@Mike, вероятно, никогда не будет из-за последствий для безопасности.

Santiago Corredoira 30.04.2015 12:12

Я создал простую в использовании библиотеку Angular ngxyz-c2c, если вам это нужно.

Ankit Singh 13.12.2019 00:32

Лично я предпочитаю сторонних разработчиков, например clipboardjs. clipboardjs: clipboardjs.com vue-clipboard: zhuowenli.github.io/vue-clipboards v-буфер обмена: vuejsexamples.com/a-clipboard-library-with-vue-js

4givN 23.01.2020 11:49
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
3 653
9
2 098 051
60

Ответы 60

Насколько я знаю, работает только в Internet Explorer.

См. Также Динамические инструменты - копирование JavaScript в буфер обмена, но он требует, чтобы пользователь сначала изменил конфигурацию, и даже тогда это не работает.

Это не мультибраузерность, как запрошено.

fnkr 12.05.2013 13:47

Чтение и изменение буфера обмена с веб-страницы вызывает проблемы с безопасностью и конфиденциальностью. Однако в 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" />

Использование флэш-памяти для простой операции копирования кажется излишним, и я рад, что для этого есть чистый JS-способ. А поскольку мы находимся в корпоративной среде. IE в порядке. Спасибо, Банди!

Eddie 26.01.2011 18:10

Объясните, пожалуйста, что делает execCommand(\\’copy\\’);, если не копирует в буфер обмена для IE? @mrBorna

RozzA 24.04.2012 22:02

Не используйте if (!document.all), а if (!r.execCommand), чтобы никто другой не реализовал это! Document.all к этому не имеет никакого отношения.

m93a 15.04.2013 22:24

Почему эти проблемы конфиденциальности никогда не возникали в течение десяти лет, когда люди использовали Flash для изменения буфера обмена? И если мы разрешаем только один способ (т.е. копирование, а не чтение его содержимого), как это вызывает беспокойство о конфиденциальности?

Muhammad bin Yusrat 06.06.2015 14:35

@MuhammadbinYusrat: является - это проблема UX, хотя и не проблема конфиденциальности. Представьте, что пользователь что-то скопировал и думает, что он знает, что находится в буфере обмена, затем просматривает ваш сайт, и внезапно в буфере обмена появляется то, о чем он не просил, и он потерял то, что скопировал в первую очередь.

awe 02.10.2015 15:01

В браузерах, отличных от Internet Explorer, вам нужно использовать небольшой объект Flash для управления буфером обмена, например

Сейчас это устарело ... ознакомьтесь с предложением GvS

Mottie 20.09.2009 19:20

Предложение от GvS использует флеш-ролик? Разве это не та же идея?

TheEmirOfGroofunkistan 08.10.2009 22:51

Другие методы скопируют простой текст в буфер обмена. Чтобы скопировать HTML (то есть вы можете вставить результаты в редактор WYSIWYG), вы можете сделать следующее в Internet Explorer Только. Этот метод принципиально отличается от других методов, поскольку браузер фактически выбирает контент визуально.

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

см. более полное решение HTML здесь stackoverflow.com/questions/34191780/…

kofifus 17.12.2015 07:48

Похоже, вы взяли код из Greasemonkey \ Кнопка JavaScript "Копировать в буфер обмена" или исходного источника этого фрагмента ...

Этот код был для Greasemonkey, отсюда и unsafeWindow. И я предполагаю, что синтаксическая ошибка в Internet Explorer возникает из-за ключевого слова const, специфичного для Firefox (замените его на var).

Ключевое слово const характерно не для Firefox, а для конкретной версии JavaScript, которую не все браузеры реализуют должным образом.

ProfK 28.02.2019 08:18

@ProfK На момент написания (10 лет назад ...) const был реализован только в Firefox и не был официальным (насколько я помню). Сегодня, конечно, почти все существующие браузеры поддерживают его.

PhiLho 26.03.2019 12:51

Начиная с Flash 10, вы можете копировать в буфер обмена только в том случае, если действие происходит от взаимодействия пользователя с объектом Flash. (Прочтите соответствующий раздел объявления Adobe Flash 10.)

Решение состоит в том, чтобы наложить Flash-объект над кнопкой «Копировать» или каким-либо другим элементом, инициирующим копирование. ZeroClipboard в настоящее время является лучшей библиотекой с этой реализацией. Опытные разработчики Flash могут просто захотеть создать свою собственную библиотеку.

Если вам нужно действительно простое решение (интеграция занимает менее 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} - цветом.

Для всех, кто заинтересован, проверьте, что Clippy используется на GitHub при копировании URL-адреса репозитория.

Radek 23.05.2011 15:19

У меня была такая же проблема с созданием настраиваемого редактирования сетки из (что-то вроде Excel) и совместимостью с Excel. Мне пришлось поддерживать выбор нескольких ячеек, копирование и вставку.

Решение: создайте текстовое поле, в которое вы будете вставлять данные для копирования пользователем (для меня, когда пользователь выбирает ячейки), установите на нем фокус (например, когда пользователь нажимает Ctrl) и выделите весь текст.

Итак, когда пользователь нажимает Ctrl + C, он получает скопированные ячейки, которые он выбрал. После тестирования просто измените размер текстового поля до одного пикселя (я не проверял, будет ли оно работать на дисплее: нет). Он прекрасно работает во всех браузерах и прозрачен для пользователя.

Вставка - вы можете сделать то же самое (отличается от вашей цели) - сосредоточьтесь на текстовом поле и перехватите события вставки с помощью onpaste (в моем проекте я использую текстовые поля в ячейках для редактирования).

Я не могу вставить пример (коммерческий проект), но вы поняли.

Из одного из проектов, над которым я работал, плагина jQuery для копирования в буфер обмена, который использует библиотеку ZeroClipboard.

Его проще использовать, чем собственный плагин Zero Clipboard, если вы интенсивно пользуетесь jQuery.

jQuery не считается законным ответом на вопрос о JavaScript, поскольку он не только раздут, но и использует ненадежные проприетарные методы Microsoft JScript, такие как innerHTML, которые неправильно регистрируют DOM.

John 23.02.2012 19:50

92 КБ на самом деле не так уж и много, он работает быстро, и вы можете использовать text() вместо innerHTML(), если хотите ..

RozzA 24.04.2012 21:59

@John: innerHTML уже давно поддерживает кроссбраузерность. Тот факт, что Microsoft изначально придумал эту идею, не делает ее ненадежной или несвободной. Также теперь наконец-то добавляется в официальную спецификацию (после того, как все основные производители браузеров уже добавили его поддержку ... вздох).

James M. Greene 17.01.2013 20:43

@John Вы жалуетесь на то, что jQuery недостаточно JavaScripty в ответе, использующем Flash;)

Max Nanasy 19.04.2013 06:12

Есть много вещей, которые стандартизированы, но не должны. Если вы решите использовать код, который МОЖЕТ работать и НЕ МОЖЕТ, то это ваша игра, а не моя. Люди, которые действительно заботятся о своей работе, всегда будут стремиться улучшить свои навыки, понимание и самих себя, а не оправдывать то, что легко использовать, но также легко сломать. На самом деле, сделать это правильно, используя настоящие стандарты, несложно, и люди могут либо делать что-то прямо сейчас, либо создавать новые неприятности в будущем.

John 20.04.2013 01:15

innerHTML в большинстве случаев лучше альтернатив. Слезь с высокого коня! Это быстрее, эффективнее и не требует повторного рендеринга страницы.

Orbiting Eden 18.06.2013 23:13

@RozzA 92KB действительно большой. Пока LTE не созреет, GPRS является Стандарт мобильной передачи данных WW, и он начинается с 1 KB/s. Посчитайте сами.

Tino 02.08.2013 11:26

Вот минималистичное использование библиотеки ZeroClipboard JS: jsfiddle.net/N36uH

Adrien Be 18.06.2014 15:40

Вот еще 2 простых примера для начала jsfiddle.net/c3DUZ и jsfiddle.net/69RLv

Adrien Be 18.06.2014 16:20

@AdrienBe ни один из ваших примеров не работает для меня ни в Firefox, ни в Chrome

bhan 04.04.2015 02:04

@AdrienBe Они здесь тоже не работают. На консоли ошибок нет, только предупреждения. Большинство из них с jshint.js

Gui Imamura 23.07.2015 16:57

@GuiImamura и bhan: извините, ребята, я пока не могу помочь. Попробуйте демонстрацию на странице ZeroClipboard и посмотрите, сможете ли вы использовать этот код для начала.

Adrien Be 24.07.2015 04:34

Страница, на которую указывает ссылка, теперь мертва, есть только мусор, проверяющий мошенничество.

MightyPork 22.03.2016 00:54

Автоматическое копирование в буфер обмена может быть опасным, и поэтому большинство браузеров (кроме Internet Explorer) очень затрудняют его. Лично я использую такой простой прием:

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

Пользователю предоставляется окно подсказки, в котором текст для копирования уже выделен. Теперь достаточно нажать Ctrl + C и Enter (чтобы закрыть окошко) - и вуаля!

Теперь операция копирования буфера обмена - безопасный, потому что пользователь делает это вручную (но довольно простым способом). Конечно, он работает во всех браузерах.

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

Но есть ограничение на количество символов, отображаемых в этом диалоговом окне, и, таким образом, есть ограничение на количество данных, которые должны быть скопированы.

Denilson Sá Maia 04.09.2011 06:32

Умно, но поддерживает только одну строку.

Aram Kocharyan 23.10.2011 12:56

Изменить функцию «подсказки» на настраиваемый модальный элемент тривиально, суть трюка заключается в использовании редактируемого поля содержимого и предварительном выборе текста, и что это не нарушает пользовательский интерфейс браузера, заставляя пользователя использовать сами действия. А ++

Jon z 17.01.2012 22:57
"... окно подсказки, в котором текст для копирования уже выделен" - но как убедиться, что текст в окне подсказки уже выделен?
Innate Imunity is The Way 17.02.2012 17:44

Во-первых, отличное решение =] Но нельзя ли воспроизвести эту функциональность без js? (Не так просто, конечно.)

b1nary.atr0phy 02.10.2012 03:23

Если ваш текст превышает 2000 символов, он будет усечен, но для небольших образцов текста он отлично работает.

RasTheDestroyer 04.09.2013 22:51

@RasTheDestroyer - усечение до 2k символов кажется проблемой Chrome, но это полезно знать, несмотря на это

Marcus Pope 19.09.2013 03:19

@AramKocharyan Я пробовал новые строки в Chrome и IE, и оба работали для меня, он представляет его без новых строк, но когда вы вставляете информацию в редактор, новые строки сохраняются - в любом случае IE10 и Chrome29

Marcus Pope 19.09.2013 03:20

Это настолько простой способ сделать это .. Спасибо .. Но текст не выделен .. Есть ли способ предварительно выделить текст?

Dibish 13.12.2013 15:08

Не работает в Firefox 25.0 на OS X. Я получаю приглашение, но текстовое поле пусто. В Chrome работает.

borisdiakur 18.12.2013 15:04

@Qix У него 579 голосов, потому что, насколько мне известно, это невозможно сделать с помощью чистого JavaScript (если только ваша единственная цель - IE). Сайты делают это «постоянно» с помощью Flash.

cubuspl42 12.05.2014 20:28

Для мобильных устройств в Chrome, когда я выделяю текст в приглашении, он, по-видимому, не позволяет мне копировать, а просто вырезать.

gab06 09.09.2020 02:06

Это расширение Ответ Чейза Зайберта с тем преимуществом, что оно будет работать для элементов IMAGE и TABLE, а не только для DIV в Internet Explorer 9.

if (document.createRange) {
    // Internet Explorer 9 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 Firefox
} else {
    // Internet Explorer 8 and earlier. This stuff won't work
    // on Internet Explorer 9.
    // (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 it 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;
  }
}

собственно я поправил код. Он работает во всех браузерах, но фактически не копируется в буфер обмена. Просто извлекает (вырезает), клонирует (копирует) контент через переменные. Кажется, я забыл об использовании.

mrBorna 17.08.2011 18:18

Я нашел следующее решение:

Обработчик нажатия клавиши создает тег «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 did 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('Failed to paste. :(');
    };
}

Применение:

enyby_clip = new EnybyClipboard(); // Init

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

При вставке он создает текстовое поле и работает так же.

PS: Возможно, это решение можно использовать для создания полноценного кросс-браузерного решения без Flash. Работает в Firefox и Chrome.

Кто-нибудь пробовал это? Звучит как отличная штука, если она действительно работает в разных браузерах!

Michael 15.02.2013 18:47
jsfiddle.net/H2FHC Демо: fiddle.jshell.net/H2FHC/show Откройте его и нажмите Ctrl + V или Ctrl + C. В FF 19.0 вилка отлично. В Chrome 25.0.1364.97 м тоже. Opera 12.14 - ОК. Safari 5.1.7 для Windows - ОК. IE - НЕИСПРАВНОСТЬ.
Enyby 28.02.2013 16:06

Для IE нужно запустить фокус на элементе внутри страницы. См. fiddle.jshell.net/H2FHC/3/show и fiddle.jshell.net/H2FHC/3 Работает в IE 9/10. IE 6/7 необходимо обработать выделение другим способом, потому что document.createRange не поддерживается.

Enyby 28.02.2013 16:33

Мне нравится этот:

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

Если пользователь не знает, как копировать текст в своей ОС, скорее всего, он тоже не знает, как вставить. Так что просто выберите его автоматически, а все остальное предоставьте пользователю.

Если скопированная ссылка должна быть вставлена ​​на тот же сайт, то простое решение - выделить текст перед нажатием простой кнопки копирования HTML, а затем при ее нажатии текстовое содержимое сохраняется в сеансе. И куда бы его ни наклеили, есть кнопка вставки.

** Знаю, это не стойкое и универсальное решение, но это что-то :)

Вы должны показать здесь примеры кода - псевдокод - это нет, чего хотят другие разработчики. В нынешнем состоянии это не очень хороший ответ.

Jimbo 05.08.2013 14:19

@Jimbo, решение ниже: для буфера обмена на основе сеанса

UserBSS1 07.08.2013 13:27

Помните, что сеанс ограничен 5 МБ (afaik).

StanE 09.11.2014 06:15

Вот буфер обмена на основе Ajax / сеанса просто для того же веб-сайта.

Обратите внимание, что сеанс должен быть включен и действителен, и это решение работает для того же сайта. Я тестировал его на CodeIgniter, но столкнулся с проблемой сеанса / Ajax, но это тоже решил эту проблему. Если вы не хотите играть с сессиями, используйте таблицу базы данных.

JavaScript / jQuery

<script type = "text/javascript">
    $(document).ready(function() {

        $("#copy_btn_id").click(function(){

            $.post("<?php echo base_url();?>ajax/foo_copy/"+$(this).val(), null,
                function(data){
                    // Copied successfully
                }, "html"
            );
        });

        $("#paste_btn_id").click(function() {

           $.post("<?php echo base_url();?>ajax/foo_paste/", null,
               function(data) {
                   $('#paste_btn_id').val(data);
               }, "html"
           );
        });
    });
</script>

HTML-контент

<input type='text' id='copy_btn_id' onclick='this.select();'  value='myvalue' />
<input type='text' id='paste_btn_id' value='' />

Код PHP

<?php
    class Ajax extends CI_Controller {

        public function foo_copy($val){
            $this->session->set_userdata(array('clipboard_val' => $val));
        }

        public function foo_paste(){
            echo $this->session->userdata('clipboard_val');
            exit();
        }
    }
?>

Это единственный ответ здесь, который не требует принуждения браузера к тому, для чего он не предназначен. Твердый +1.

Luke A. Leber 09.05.2015 01:13

Виноват. Это работает только в Internet Explorer.

Вот еще один способ скопировать текст:

<p>
    <a onclick = "window.clipboardData.setData('text', document.getElementById('Test').innerText);">Copy</a>
</p>

Это не работает в текущих версиях Chrome (V31) или FireFox (v25). Ошибка в том, что window.clipboardData не определено. С другой стороны, это работает в IE9. Итак, пока вы не заботитесь о хороших браузерах и хотите заблокировать свой сайт для использования плохих, это ваш способ сделать это!

Anthony 14.11.2013 18:13

Я не понимаю, почему так много глупых ответов. w3schools.com/howto/tryit.asp?filename=tryhow_js_copy_clipbo‌ ard

Martian2049 08.02.2018 04:56

Если вы читаете текст из буфера обмена в расширении Chrome с разрешением clipboardRead, вы можете использовать следующий код:

function readTextFromClipboardInChromeExtension() {
    var ta = $('<textarea/>');
    $('body').append(ta);
    ta.focus();
    document.execCommand('paste');
    var text = ta.val();
    ta.blur();
    ta.remove();
    return text;
}

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>

Если вам нужна поддержка без Flash для iOS, просто добавьте запасной вариант:

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

кроссбраузерность с Flash? не работает в iOS и Android 4.4

Raptor 27.01.2014 14:29

См. Обновленный ответ. Это позволяет меньше шагов для пользователей flash и откат для всех остальных.

Justin 27.01.2014 21:38

в нем миллиард строк кода. это абсолютно насмешки. лучше вообще этого не делать, чем включать такого монстра в проект

vsync 27.10.2014 14:25

Существует простая версия gist.github.com/JamesMGreene/8698897, которая составляет 20K, которая не имеет всех наворотов в версии 74k. Ни то, ни другое не очень большое. Я предполагаю, что большинство пользователей в порядке с дополнительными миллисекундами, которые потребуются для загрузки файла размером 74 КБ или 20 КБ, поэтому копирование / вставка выполняется одним щелчком мыши вместо двух.

Justin 27.10.2014 18:35

@Justin Я просто не могу заставить его работать локально, даже если я копирую и вставляю примеры (я вношу минимальные изменения, например, значение src в тегах скрипта). Я считаю, что их документация хороша, но неэффективна.

Gui Imamura 23.07.2015 16:47

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

Это работает только при вводе в командной строке Chrome. Когда я добавляю его в свой код, функция копирования не определяется.

EricP 01.10.2014 22:23

@JoeCoder благодарим вас за явное указание на это, поскольку я имел в виду, что это должно быть очевидно из ссылки, но, оглядываясь назад, это не очень очевидно.

drzaus 03.10.2014 18:08

Я недавно написал сообщение в техническом блоге по этой самой проблеме (я работаю в Lucidchart, и мы недавно провели капитальный ремонт нашего буфера обмена).

Копирование обычного текста в буфер обмена относительно просто, если вы попытаетесь сделать это во время события копирования системы (пользователь нажимает Ctrl + C или использует меню браузера).

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, что является единственным кроссбраузерным способом сделать это (насколько я понимаю).

Помимо этого, есть несколько вариантов для каждого браузера.

Это самый простой вариант в Internet Explorer, где вы можете получить доступ к объекту clipboardData в любое время из JavaScript с помощью:

window.clipboardData

(Однако, когда вы пытаетесь сделать это вне системного события вырезания, копирования или вставки, Internet Explorer предложит пользователю предоставить разрешение буфера обмена веб-приложения.)

В Chrome вы можете создать расширение Chrome, которое даст вам разрешения буфера обмена (это то, что мы делаем для Lucidchart). Тогда для пользователей с установленным расширением вам просто нужно самостоятельно запустить системное событие:

document.execCommand('copy');

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

В сообщении блога не упоминается (я надеюсь обновить его в ближайшем будущем), это возможность запускать вырезание и копирование с помощью execCommand. Это поддерживается в IE10 +, Chrome 43+ и Opera29 +. Об этом читайте здесь. updates.html5rocks.com/2015/04/cut-and-copy-commands

Richard Shurtz 21.05.2015 00:30

Проблема в том, что он перехватывает другие обычные события копирования.

Brock Adams 04.02.2017 08:32

NB! Это обнюхивание браузера ПЛОХО. Обнюхивайте особенности. Вы затрудняете обновление IE.

odinho - Velmont 03.12.2018 14:31

Вы не можете этого сделать из соображений безопасности. Вы должны выбрать Flash для копирования в буфер обмена.

Я предлагаю этот: http://zeroclipboard.org/

Это немного комбинация других ответов.

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

Как скопировать данные напрямую из переменной. Т.е. var str = "word"; ?

user1108948 05.02.2016 21:49

Сообщение переменной не используется

Voyager 25.04.2019 09:50

Лучше использовать '<textarea class = "textToCopyInput" /> </textarea> в случае, если textToCopy содержит \n

Voyager 25.04.2019 11:07

clipboard.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.info('success'); },
    function(err){console.info('failure', err);
  });

});
</script>

clipboard.js также находится на GitHub.

Note: This has been deprecated now. Migrate to here.

Эта библиотека используется angular.io для его Tour of Hero и отката в изящном режиме для браузера, не поддерживающего execCommand, путем отображения предварительно выбранного текста, который пользователь должен просто скопировать.

John-Philip 30.01.2017 17:43

Похоже, clipboard.js был заменен или разветвлен, но, похоже, он живет и активно поддерживается в npmjs.com/package/clipboard

Joao 19.06.2019 01:19

В дополнение к Обновленный ответ Дина Тейлора (июль 2015 г.) я написал метод jQuery, похожий на его пример.

jsFiddle

/**
* Copies the current selected text to the SO clipboard
* This method must be called from an event to work with `execCommand()`
* @param {String} text Text to copy
* @param {Boolean} [fallback] Set to true shows a prompt
* @return Boolean Returns `true` if the text was copied or the user clicked on accept (in prompt), `false` otherwise
*/
var CopyToClipboard = function(text, fallback){
    var fb = function () {
        $t.remove();
        if (fallback !== undefined && fallback) {
            var fs = 'Please, copy the following text:';
            if (window.prompt(fs, text) !== null) return true;
        }
        return false;
    };
    var $t = $('<textarea />');
    $t.val(text).css({
        width: '100px',
        height: '40px'
    }).appendTo('body');
    $t.select();
    try {
        if (document.execCommand('copy')) {
            $t.remove();
            return true;
        }
        fb();
    }
    catch (e) {
        fb();
    }
};

Обновление 2015: в настоящее время есть способ использовать document.execCommand для работы с буфером обмена.

clipboard.js обеспечивает кроссбраузерный способ работы с буфером обмена (поддержка браузера).

Я собирался использовать clipboard.js, но у него нет мобильного решения (пока) ... поэтому я написал супер-маленькую библиотеку:

Cheval

Это либо скопирует текст (рабочий стол, Android и Safari 10+), либо, по крайней мере, выделит текст (более старые версии iOS). В уменьшенном виде это чуть более 1 КБ. В настольном Safari (до версии 10) он сообщает пользователю "Нажмите Command + C, чтобы скопировать". Вам также не нужно писать какой-либо JavaScript, чтобы использовать его.

Я использовал clipboard.js.

Мы можем получить его на npm:

npm install clipboard --save

А также на Беседка

bower install clipboard --save

Использование и примеры находятся на https://zenorocha.github.io/clipboard.js/.

Я боялся, что это несовместимо с динамическим контентом, но это так ;-) Я думаю, что это лучшее решение СЕЙЧАС, чем старое решение 2008 года.

BENARD Patrick 05.01.2016 18:19

Поскольку Chrome 42+ и Firefox 41+ теперь поддерживают команду document.execCommand ('копия'), я создал несколько функций для кросс-браузерного копирования в буфер обмена, используя комбинацию Старый ответ Тима Дауна и Ответ разработчика Google:

function selectElementContents(el) {
    // Copy textarea, pre, div, etc.
    if (document.body.createTextRange) {
        // Internet Explorer
        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.info('Copy command was ' + msg);
        }
        catch (err) {
            console.info('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>

Спасибо за подведение итогов! В вашем коде есть небольшие ошибки: вы дважды определили переменную "диапазон" (var range = document.createRange ()).

Christian Engel 17.11.2015 11:59

Вы правы @ChristianEngel. Я удалил второй. Не знаю, как он туда попал.

Jeff Baker 19.11.2015 05:11

Следующий подход работает в Chrome, Firefox, Internet Explorer и Edge, а также в последних версиях Safari (поддержка копирования была добавлена ​​в версии 10, выпущенной в октябре 2016 года).

  • Создайте текстовое поле и установите для него текст, который вы хотите скопировать в буфер обмена.
  • Добавьте текстовое поле в DOM.
  • Выделите текст в текстовой области.
  • Вызовите document.execCommand ("копия")
  • Удалите текстовое поле из dom.

Примечание: вы не увидите текстовое поле, поскольку оно добавляется и удаляется при одном синхронном вызове кода Javascript.

Некоторые вещи, на которые следует обратить внимание, если вы реализуете это самостоятельно:

  • По соображениям безопасности это можно вызвать только из обработчика событий, такого как щелчок (как и при открытии окон).
  • Internet Explorer покажет диалоговое окно разрешений при первом обновлении буфера обмена.
  • Internet Explorer и Edge будут прокручиваться, когда текстовое поле находится в фокусе.
  • execCommand () может вызывать в некоторых случаях.
  • Новые строки и вкладки могут проглотить, если вы не используете текстовое поле. (В большинстве статей рекомендуется использовать div)
  • Текстовое поле будет отображаться, пока отображается диалоговое окно Internet Explorer, вам нужно либо скрыть его, либо использовать специальный интерфейс clipboardData API для Internet Explorer.
  • В 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 window.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/

Хороший ответ: кроссбраузерная поддержка, обработка ошибок + очистка. Что касается сегодняшней новой поддержки queryCommandSupported, копирование в буфер обмена теперь возможно в Javascript, и это должен быть принятый ответ вместо неудобного обходного пути 'window.prompt («Копировать в буфер обмена: Ctrl + C, Enter», текст) ». window.clipboardData поддерживается в IE9, поэтому вам следует добавить IE9 в список поддержки браузера, и я думаю, может быть, IE8 и предыдущие также, но необходимо проверить.

user627283 01.12.2015 20:38

Ага. IE 8/9 Должно быть в порядке. Наше приложение их не поддерживает. Так что я не тестировал. IE прекращает поддержку в январе, так что я не особо волнуюсь. Надеюсь, поддержка Safari скоро появится. Я уверен, что это на их радарах.

Greg Lowe 02.12.2015 01:08

@SantiagoCorredoira: В 2016 году это заслуживает общепринятого ответа. Пожалуйста, рассмотрите возможность переназначения BGT (большая зеленая галочка).

Lawrence Dol 22.04.2016 04:25

@drooh Поддерживается в Safari 10+. Safari 10 все еще находится в стадии бета-тестирования. Он будет выпущен вместе с MacOS 10.12 (вероятно, в октябре).

Greg Lowe 02.08.2016 04:43

textarea.select () у меня не работает в Chrome. Функция существует, но содержимое текстовой области фактически не попадает в буфер обмена.

mwag 09.05.2017 22:21

Вы пробовали код на JS Fiddle? jsfiddle.net/fx6a6n6x У меня это работает в chrome и canary на MacOS.

Greg Lowe 10.05.2017 01:54

Если фокус не находится в html-документе, например, вы просто щелкнули панель задач Windows, а затем нажали кнопку «Копировать» в своем html-документе, функция вернет true, но не сможет скопировать. Так было в Firefox 55 сегодня. Но спасибо, что поделились этим, я использую его, очень признателен.

Noitidart 07.08.2017 03:16

@Noitidart Я протестирован, и он отлично работает для firefox 54, chrome 60 и браузера Edge, даже когда фокус не находится в html-документе, ошибка, которую вы имеете, вероятно, специфична для версии FF 55

Tosin John 12.08.2017 04:01

Спасибо, @TosinJohn - пожалуйста, откройте инструменты разработчика, затем сфокусируйтесь на них, затем с помощью первого щелчка - щелкните <button>, который запускает копирование, он должен вернуть истину, но копия не удастся.

Noitidart 12.08.2017 07:59

@Noitidart Здесь он по-прежнему отлично работает, сосредоточение внимания на инструментах разработчика не остановило его. И, кстати, что будет делать обычный пользователь веб-приложения с инструментами разработчика?

Tosin John 12.08.2017 19:48

Спасибо @TosinJohn - это очень интересно. Я не знаю, почему моя первая копия выходит из строя. Большое спасибо за этот тест. Да, правда, их может не быть в инструментах разработчика, но у них может быть два окна рядом друг с другом, и они могут щелкнуть из одного окна в мое веб-приложение (сначала щелкните копию).

Noitidart 12.08.2017 20:26

команда: clipboardData, setData ("Text", text) не копирует форматированный текст, поэтому, например, если вы скопировали текст, содержащий несколько строк (с символами новой строки в качестве разделителей), символ новой строки не будет часть скопированной строки, и вместо этого вы получите одну длинную строку

shayuna 04.03.2018 14:14
Пользователи jQuery UI: обратите внимание, что вы столкнетесь с проблемами с этим методом, если попытаетесь использовать эту функцию из модального диалогового окна. Я подозреваю, что это потому, что модальный интерфейс jQuery UI управляет / манипулирует фокусом документа. Если это соответствует вашему варианту использования, можно сначала закрыть модальное диалоговое окно, а затем скопировать текст. Или просто использовать немодальное диалоговое окно. Я подозреваю, что вы также можете изменить эту функцию, чтобы она добавляла текстовое поле в модальное окно, а не в тело.
rinogo 31.12.2018 23:30

Я, вероятно, задаю неправильные вопросы в неправильном месте, но все равно хочу попробовать ... можно ли сделать это в виде двух лайнеров, используя какой-то надежный, всегда обновляемый импорт из gitlab или что-то в этом роде?

cregox 19.09.2019 10:52

нуждается в исправлении, есть отличное средство «если» для проверки доступности window.clipboardData.setData, но затем, если оно проходит, код обходит окно и напрямую попадает в «clipboardData»! Я добавил код asis в CRA, и он разлетелся, просто нужно окно. приставка

Andy Lorenz 16.06.2020 19:26

После поиска решения, поддерживающего Safari и другие браузеры (Internet Explorer 9 и более поздние версии),

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

JavaScript

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

Ответов уже много, но хотелось бы добавить еще один (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.');
}

Мне пришлось скопировать текст без полей ввода (текст в любом теге div / span) со страницы и придумал следующий код. Единственная уловка - иметь скрытое поле, но типа ТЕКСТ. Он не будет работать со скрытым типом.

function copyToClipboard(sID) {
    var aField = document.getElementById("hiddenField");

    aField.hidden = false;
    aField.value  = document.getElementById(sID).textContent;
    aField.select();
    document.execCommand("copy");
    alert("Following text has been copied to the clipboard.\n\n" + aField.value);
    aField.hidden = true;
}

И в HTML добавьте следующее:

input type = "text" id = "hiddenField" style = "width:5px;border:0" />
...

Я нашел следующее решение:

У меня есть текст в скрытом вводе. Поскольку 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;
}

Я скомпилировал несколько функций в простое решение, охватывающее все случаи, с возможностью быстрого отката в случае необходимости.

window.copyToClipboard = function(text) {
  // Internet Explorer specific
  if (window.clipboardData && window.clipboardData.setData) {
    return clipboardData.setData("Text", text);
  }

  // All other modern browsers
  target = document.createElement("textarea");
  target.style.position = "absolute";
  target.style.left = "-9999px";
  target.style.top = "0";
  target.textContent = text;
  document.body.appendChild(target);
  target.focus();
  target.setSelectionRange(0, target.value.length);

  // Copy the selection of fall back to prompt
  try {
    document.execCommand("copy");
    target.remove();
    console.info('Copied to clipboard: "'+text+'"');
  }
  catch(e) {
    console.info("Can't copy string on this browser. Try to use Chrome, Firefox or Opera.")
    window.prompt("Copy to clipboard: Ctrl+C, Enter", text);
  }
}

Протестируйте здесь: https://jsfiddle.net/jv0avz65/

Я собрал решение, представленное здесь @ 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 выше.

Я собрал то, что считаю лучшим.

  • Использует 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 programmatic 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')

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

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

    // Create temporary 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;
}
textarea.style.position = 'fixed'; будет лучше
liubiantao 15.09.2017 09:46

@liubiantao, почему это так?

mmm 12.09.2020 15:08

Вот мой взгляд на это ...

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

@nikksan как скопировать строку с \n?

sof-03 22.05.2018 13:17

@ sof-03 используйте textarea вместо input и добавьте \r\n для разрыва строки

nikksan 22.05.2018 14:18

Не работает в Microsoft Edge 42.17134.1.0 на Win10x64

Honsa Stunna 30.05.2018 17:26

Я скопировал ваш ответ. Он работает в хроме, и это все, что мне нужно.

user875234 15.11.2018 17:51

Это простейшее решение, которое работает с Firefox v68.0.2 (64-бит).

Arya 24.08.2019 08:37

По какой-то причине мой обычный «создать скрытый ввод или текстовое поле, затем выбрать его и execCommand» не работал, и это было, безусловно, лучшее решение, перечисленное здесь, хотя другие всеобъемлющие и, как и полные страницы википедии, это работало хорошо для меня так +1

Justin 01.02.2021 01:20

Это была единственная вещь, с которой я когда-либо работал, после того, как искал различные способы по всему Интернету. Это грязная тема. По всему миру опубликовано множество решений, и большинство из них работают с нет. Это сработало для меня:

ПРИМЕЧАНИЕ. Этот код будет работать только при выполнении как прямой синхронный код для чего-то вроде метода onClick. Если вы вызовете асинхронный ответ на Ajax или каким-либо другим асинхронным способом, это не сработает.

copyToClipboard(text) {
    var copyText = document.createElement("input");
    copyText.type = "text";
    document.body.appendChild(copyText);
    copyText.style = "display: inline; width: 1px;";
    copyText.value = text;
    copyText.focus();
    document.execCommand("SelectAll");
    document.execCommand("Copy");
    copyText.remove();
}

Я понимаю, что этот код будет отображать компонент шириной в 1 пиксель на экране в течение миллисекунды, но решил не беспокоиться об этом, и это то, что другие могут решить, если возникнет реальная проблема.

Чтобы скопировать выделенный текст («Текст для копирования») в буфер обмена, создайте букмарклет (закладку браузера, которая выполняет JavaScript) и выполните его (щелкните по нему). Это создаст временную текстовую область.

Код с GitHub:

https://gist.github.com/stefanmaric/2abf96c740191cda3bc7a8b0fc905a7d

(function (text) {
  var node = document.createElement('textarea');
  var selection = document.getSelection();

  node.textContent = text;
  document.body.appendChild(node);

  selection.removeAllRanges();
  node.select();
  document.execCommand('copy');

  selection.removeAllRanges();
  document.body.removeChild(node);
})('Text To Copy');

Это единственное, что у меня сработало:

let textarea = document.createElement('textarea');
textarea.setAttribute('type', 'hidden');
textarea.textContent = 'the string you want to copy';
document.body.appendChild(textarea);
textarea.select();
document.execCommand('copy');

Используя функцию JavaScript с помощью try/catch, вы можете даже лучше обрабатывать ошибки, делая это следующим образом:

copyToClipboard() {
    let el = document.getElementById('Test').innerText
    el.focus(); // el.select();
    try {
        var successful = document.execCommand('copy');
        if (successful) {
            console.info('Copied Successfully! Do whatever you want next');
        }
        else {
            throw ('Unable to copy');
        }
    }
    catch (err) {
        console.warn('Oops, Something went wrong ', err);
    }
}

Что здесь ES7?

Boaz 01.03.2018 02:26

блок try / catch

Adeel Imran 01.03.2018 13:00

Если только я не понимаю, что вы имеете в виду, try...catch существует со времен "ES3" (то есть за последние 20 лет или около того).

Boaz 01.03.2018 13:17

Извините, сэр, это было моим незнанием. Я поправил свой пост.

Adeel Imran 01.03.2018 13:45

Скопируйте текст из ввода 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>

Примечание:Метод document.execCommand() не поддерживается в Internet Explorer 9 и более ранних версиях.

Источник: W3Schools - Копировать текст в буфер обмена

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

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

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

Я очень успешно использую это (без 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).

Вот как это сделать в 2018 году:

async copySomething(text?) {
  try {
    const toCopy = text || location.href;
    await navigator.clipboard.writeText(toCopy);
    console.info('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-адрес страницы.

Можно сделать еще больше гимнастики для буфера обмена. См. Дополнительную информацию здесь:

Разблокировка доступа к буферу обмена

вы связались с localhost

Joe Warner 06.08.2018 22:21

Имейте в виду, что это не работает в Safari (версия 11.1.2).

arjunattam 20.08.2018 13:45

@ arjun27 Что ж, надеюсь, когда-нибудь Apple наверстает упущенное. Хотя этот caniuse.com/#feat=clipboard показывает, что упомянутая выше версия частично поддерживается.

KhoPhi 20.08.2018 21:23

Полезный контент; бесполезное отношение.

kano 05.11.2018 11:35

Я получаю для обеих функций readText, writeText обещание в отклоненном состоянии

ramin 09.12.2018 23:17

Согласно предоставленной ссылке, "navigator.clipboard поддерживается только для страниц, обслуживаемых через HTTPS".

TimH - Codidact 20.12.2018 22:35

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

Примечание

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

Применение

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

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

Использование document.execCommand сделает всю работу за вас ...

Используя это, вы также можете использовать резать, копировать и вставить ...

Это одна простая функция копирования из буфера обмена, которая копирует все из входного текста ...

function copyInputText() {
  var copyText = document.querySelector("#input");
  copyText.select();
  document.execCommand("copy");
}

document.querySelector("#copy").addEventListener("click", copyInputText);
<input id = "input" type = "text" />
<button id = "copy">Copy</button>

Для получения дополнительной информации см. Взаимодействовать с буфером обмена (надстройка).

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

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

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

Это автономный класс, который гарантирует невозможность перепрограммирования временного textarea, помещая его за пределы экрана.

Это работает в Safari (рабочий стол), Firefox и Chrome.

// ================================================================================
// ClipboardClass
// ================================================================================
var ClipboardClass = (function() {

    function copyText(text) {
        // Create a temporary 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
    };

})();
function copytoclipboard(element) {

    var $temp = $("<input>");
    $("body").append($temp);
    $temp.val('0' + element).select();
    document.execCommand("copy");
    $temp.remove();
}

    $("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>

Я прочитал все ответы, по состоянию на 1 июня 2020 года я изо всех сил пытался решить эту проблему, когда наконец нашел документацию:

$("td").click(function (e) {
    var clickedCell = $(e.target).closest("td");
    navigator.clipboard.writeText(clickedCell.text());
});

Он запишет текст выбранной ячейки в буфер обмена браузера.

Вы можете изменить селекторы «td» на все, что захотите, вы можете добавить console.info для функций отладки и / или предупреждений.

Вот документация: https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/writeText

Нет совместимости с IE

lance.dolan 10.11.2020 04:31
document.querySelector('#some_your_textfield_id').select();
document.execCommand('copy');

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

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

Это решение было найдено здесь. document.execCommand("copy"); не поддерживается в Internet Explorer 8 и более ранних версиях.

const copyBtn =  document.getElementById("copyBtn");
const input = document.getElementById("input");

function copyText() {
  const value = input.value;
  
  input.select(); // selects the input variable as the text to be copied
  input.setSelectionRange(0, 99999); // this is used to set the selection range for mobile devices
  
  document.execCommand("copy"); // copies the selected text
  
  alert("Copied the text " + value); // displays the copied text in a prompt
}

copyBtn.onmousedown = function () {
  copyText();
}
<input type = "text" id = "input" placeholder = "Type text to copy... "/>
<button id = "copyBtn">
  Copy
</button>

Команда execCommand считается устаревшей: developer.mozilla.org/en-US/docs/Web/API/Document/execComman‌ d

Jarede 12.01.2021 15:25

Простое, готовое к использованию и не устаревшее решение:

function copyToClipboard(elementIdToCopy, elementIdToNotifyOutcome) {
    const contentToCopy = document.getElementById(elementIdToCopy).innerHTML;
    const elementToNotifyOutcome = document.getElementById(elementIdToNotifyOutcome);

    navigator.clipboard.writeText(contentToCopy).then(function() {
        elementToNotifyOutcome.classList.add('success');
        elementToNotifyOutcome.innerHTML = 'Copied!';
    }, function() {
        elementToNotifyOutcome.classList.add('failure');
        elementToNotifyOutcome.innerHTML = 'Sorry, did not work.';
    });
}

Приведенную ниже функцию можно использовать для копирования в буфер обмена:

copyToclipboard = (event, text) => {
    var container = event.currentTarget;
    let tempInnerHtml = container.innerHTML;
    container.innerHTML = text;
    window.getSelection().removeAllRanges();
    let range = document.createRange();
    range.selectNode(container);
    window.getSelection().addRange(range);
    document.execCommand('copy');
    window.getSelection().removeAllRanges();
    container.innerHTML = tempInnerHtml;
}

execCommand теперь считается устаревшим: developer.mozilla.org/en-US/docs/Web/API/Document/execComman‌ d

Jarede 12.01.2021 15:16

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

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

Другие вопросы по теме