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

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


person Santiago Corredoira    schedule 30.12.2008    source источник
comment
Просто любопытно, что вы хотите скопировать в буфер обмена, что пользователь не может сделать сам?   -  person scunliffe    schedule 30.12.2008
comment
Ничего особенного. Они могут сделать это сами, но я хочу предложить также возможность нажатия кнопки, не беспокоясь о выборе правильной части текста.   -  person Santiago Corredoira    schedule 31.12.2008
comment
Это длинное сообщение в блоге содержит множество способов сделать это: Доступ к системному буферу обмена с помощью JavaScript - Святой Грааль?   -  person Aaron Digulla    schedule 21.04.2011
comment
Это дает браузеру неопределенное исключение в IE, а также в FF   -  person Jagadeesh    schedule 22.02.2013
comment
Если мы можем поместить текст в буфер обмена пользователя, мы можем испортить его буфер обмена.   -  person Frank Fang    schedule 11.06.2014
comment
Это все еще не полностью поддерживается. Вы можете получить поддержку на странице Могу ли я использовать API буфера обмена? в котором подробно описывается поддержка документа API буфера обмена W3C.   -  person mkobit    schedule 29.04.2015
comment
@Mike, вероятно, никогда не будет из-за последствий для безопасности.   -  person Santiago Corredoira    schedule 30.04.2015
comment
Я создал простую в использовании библиотеку Angular ngxyz-c2c, если вам это нужно.   -  person Ankit Singh    schedule 13.12.2019
comment
Лично я предпочитаю сторонние программы, например clipboardjs. clipboardjs: clipboardjs.com vue-clipboards: zhuowenli.github.io/vue-clipboards v-clipboard: vuejsexamples.com/a-clipboard-library-with-vue-js   -  person 4givN    schedule 23.01.2020


Ответы (61)


Обзор

Существует три основных API браузера для копирования в буфер обмена:

  1. API асинхронного буфера обмена [navigator.clipboard.writeText]

    • Text-focused portion available in Chrome 66 (March 2018)
    • Доступ является асинхронным и использует JavaScript Promises, может быть написан так, чтобы пользователь безопасности запрашивал (если отображается) не прерывают JavaScript на странице.
    • Текст можно скопировать в буфер обмена прямо из переменной.
    • Поддерживается только на страницах, обслуживаемых по HTTPS.
    • На 66 страницах Chrome неактивные вкладки могут записываться в буфер обмена без запроса разрешений.
  2. document.execCommand('copy')

    • Most browsers support this as of ~April 2015 (see Browser Support below).
    • Доступ является синхронным, то есть останавливает JavaScript на странице до завершения, включая отображение и взаимодействие пользователя с любыми запросами безопасности.
    • Текст считывается из модели DOM и помещается в буфер обмена.
    • Во время тестирования ~ апрель 2015 года было замечено, что только Internet Explorer отображает запросы разрешений при записи в буфер обмена.
  3. Переопределение события копирования

    • See Clipboard API documentation on Overriding the copy event.
    • Позволяет вам изменять то, что появляется в буфере обмена из любого события копирования, может включать другие форматы данных, кроме обычного текста.
    • Здесь не рассматривается, поскольку не дает прямого ответа на вопрос.

Общие замечания по развитию

Не ожидайте, что команды, связанные с буфером обмена, будут работать, пока вы тестируете код в консоли. Как правило, страница должна быть активной (API асинхронного буфера обмена) или требует взаимодействия с пользователем (например, щелчка пользователя), чтобы разрешить (document.execCommand('copy')) доступ к буферу обмена, подробнее см. Ниже.

ВАЖНО (указано здесь 2020/02/20)

Обратите внимание: поскольку этот пост был изначально написан прекращение поддержки разрешений в IFRAME с несколькими источниками и других песочница IFRAME предотвращает работу встроенных демонстраций кнопок фрагмента кода и примера codepen.io в некоторых браузерах (включая Chrome и Microsoft Edge).

Для разработки создайте свою собственную веб-страницу, обслуживайте эту страницу через соединение HTTPS для тестирования и разработки.

Вот тестовая / демонстрационная страница, демонстрирующая работу кода: https://deanmarktaylor.github.io/clipboard-test/

Асинхронный + резервный

Из-за уровня поддержки браузером нового 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 асинхронного буфера обмена

Обратите внимание, что есть возможность запросить разрешение и проверить доступ к буферу обмена через API разрешений в Chrome 66.

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 ('копия')

Остальная часть этой статьи посвящена нюансам и деталям document.execCommand('copy') API.

Поддержка браузера

Увеличилась поддержка document.execCommand('copy') JavaScript, см. Ссылки ниже для обновлений браузера:

Простой пример

(may not work embedded in this site, read "important" note above)

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>

Сложный пример: копирование в буфер обмена без отображения ввода

Приведенный выше простой пример отлично работает, если на экране виден элемент textarea или input.

В некоторых случаях вам может потребоваться скопировать текст в буфер обмена без отображения элемента input / textarea. Это один из примеров решения этой проблемы (просто вставка элемента, копирование в буфер обмена, удаление элемента):

Протестировано с Google Chrome 44, Firefox 42.0a1 и Internet Explorer 11.0.8600.17814.

(may not work embedded in this site, read "important" note above)

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 the 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 the 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 the 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') вызовы должны происходить как прямой результат действия пользователя, например обработчик события click. Это мера по предотвращению беспорядка с буфером обмена пользователя, когда он этого не ожидает.

См. сообщение разработчиков Google здесь для получения дополнительной информации.

API буфера обмена

Обратите внимание, что полный проект спецификации API буфера обмена можно найти здесь: https://w3c.github.io/clipboard-apis/

Поддерживается?

  • document.queryCommandSupported('copy') должен вернуть true, если команда поддерживается браузером.
  • и document.queryCommandEnabled('copy') вернут true, если document.execCommand('copy') будет успешным, если вызвать сейчас. Проверка того, что команда была вызвана из потока, инициированного пользователем, и соблюдены другие требования.

Однако в качестве примера проблем совместимости браузера Google Chrome с ~ апреля по ~ октябрь 2015 г. возвращал true из document.queryCommandSupported('copy') только в том случае, если команда была вызвана из потока, инициированного пользователем.

Обратите внимание на детали совместимости ниже.

Сведения о совместимости браузера

В то время как простой вызов document.execCommand('copy'), заключенный в блок _27 _ / _ 28_, вызываемый в результате щелчка пользователя, обеспечит вам максимальную совместимость, использование следующего имеет некоторые оговорки:

Любой вызов document.execCommand, document.queryCommandSupported или document.queryCommandEnabled должен быть заключен в блок _32 _ / _ 33_.

Различные реализации и версии браузеров при вызове выдают разные типы исключений вместо того, чтобы возвращать false.

Различные реализации браузеров все еще находятся в стадии разработки, а Clipboard API все еще находится в стадии разработки, поэтому не забудьте сделать ваше тестирование.

person Dean Taylor    schedule 12.06.2015
comment
Извините за нарушение вечеринки, но document.execCommand is obsolete. См. developer.mozilla.org/en-US/docs/Web. / API / Document / execCommand - person tnkh; 12.10.2020
comment
@tnkh конечно, но замена (API буфера обмена) еще не полностью запечена и не поддерживается. - person forresto; 03.05.2021
comment
Мы называем их браузерами! (представьте, что я говорю это в конце постановки для Аристократов!) - person Andrew Koster; 15.07.2021

Автоматическое копирование в буфер обмена может быть опасным, и поэтому большинство браузеров (кроме 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>

person Jarek Milewski    schedule 19.05.2011
comment
Но есть ограничение на количество символов, отображаемых в этом диалоговом окне, и, таким образом, есть ограничение на количество данных, которые должны быть скопированы. - person Denilson Sá Maia; 04.09.2011
comment
Умно, но поддерживает только одну строку. - person Aram Kocharyan; 23.10.2011
comment
Изменить функцию подсказки на настраиваемый модальный элемент тривиально, суть трюка заключается в использовании редактируемого поля содержимого и предварительного выбора текста, и это не нарушает пользовательский интерфейс браузера, заставляя пользователя выполнять действие самостоятельно. . А ++ - person Jon z; 17.01.2012
comment
... окно подсказки, где текст для копирования уже выделен - но как убедиться, что текст в поле подсказки уже выделен? - person Tomas; 17.02.2012
comment
Во-первых, отличное решение =] Но нельзя ли воспроизвести эту функциональность без js? (Не так просто, конечно.) - person b1nary.atr0phy; 02.10.2012
comment
Если ваш текст превышает 2000 символов, он будет усечен, но для небольших образцов текста он отлично работает. - person RasTheDestroyer; 04.09.2013
comment
@RasTheDestroyer - усечение до 2k символов кажется проблемой Chrome, но это полезно знать, несмотря на это - person Marcus Pope; 19.09.2013
comment
@AramKocharyan Я пробовал новые строки в Chrome и IE, и оба работали для меня, он представляет его без новых строк, но когда вы вставляете информацию в редактор, новые строки сохраняются - в любом случае IE10 и Chrome29 - person Marcus Pope; 19.09.2013
comment
Это настолько простой способ сделать это .. Спасибо .. Но текст не выделен .. Есть ли способ предварительно выделить текст? - person Dibish; 13.12.2013
comment
Не работает в Firefox 25.0 на OS X. Я получаю приглашение, но текстовое поле пусто. В Chrome работает. - person borisdiakur; 18.12.2013
comment
@Qix У него 579 голосов, потому что, насколько мне известно, это невозможно сделать с помощью чистого JavaScript (если только ваша единственная цель - IE). Сайты постоянно делают это с помощью Flash. - person cubuspl42; 12.05.2014
comment
Для мобильных устройств в Chrome, когда я выделяю текст в приглашении, он, по-видимому, не позволяет мне копировать, а просто вырезать. - person gab06; 09.09.2020
comment
Почему бы просто не использовать кнопку ‹onclick = selectText ()› Выделите текст (нажмите Ctrl + C, чтобы скопировать) ‹/button› и функцию selectText () {const input = document.getElementById ('text-box'); input.focus (); input.select (); } Думаю, это побыстрее. - person G M; 28.04.2021

Следующий подход работает в 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/

person Greg Lowe    schedule 26.11.2015
comment
Хороший ответ: кроссбраузерная поддержка, обработка ошибок + очистка. Что касается сегодняшней новой поддержки queryCommandSupported, копирование в буфер обмена теперь возможно в Javascript, и это должен быть принятый ответ вместо неудобного обходного пути window.prompt (Копировать в буфер обмена: Ctrl + C, Enter, текст). window.clipboardData поддерживается в IE9, поэтому вам следует добавить IE9 в список поддержки браузера, и я думаю, может быть, IE8 и предыдущие также, но необходимо проверить. - person user627283; 01.12.2015
comment
Ага. IE 8/9 Должно быть нормально. Наше приложение их не поддерживает. Так что я не тестировал. IE прекращает поддержку в январе, так что я не слишком волнуюсь. Надеюсь, скоро появится поддержка Safari. Я уверен, что это на их радарах. - person Greg Lowe; 02.12.2015
comment
@SantiagoCorredoira: В 2016 году это заслуживает общепринятого ответа. Пожалуйста, рассмотрите возможность переназначения BGT (большая зеленая галочка). - person Lawrence Dol; 22.04.2016
comment
@drooh Поддерживается в Safari 10+. Safari 10 все еще находится в стадии бета-тестирования. Он будет выпущен вместе с MacOS 10.12 (вероятно, в октябре). - person Greg Lowe; 02.08.2016
comment
textarea.select () у меня не работает в Chrome. Функция существует, но содержимое текстовой области фактически не попадает в буфер обмена. - person mwag; 09.05.2017
comment
Вы пробовали код на JS Fiddle? jsfiddle.net/fx6a6n6x Это работает для меня в Chrome и Canary на MacOS. - person Greg Lowe; 10.05.2017
comment
Если фокус не находится в html-документе, например, вы просто щелкнули панель задач Windows, а затем нажали кнопку «Копировать» в своем html-документе, функция возвращает true, но не может скопировать. Так было с Firefox 55 сегодня. Но спасибо, что поделились этим, я использую его, очень признателен. - person Noitidart; 07.08.2017
comment
@Noitidart Я протестирован, и он отлично работает для firefox 54, chrome 60 и браузера Edge, даже когда фокус не находится в html-документе, ошибка, которую вы имеете, вероятно, специфична для версии FF 55 - person Tosin John; 12.08.2017
comment
Спасибо, @TosinJohn - пожалуйста, откройте инструменты разработчика, затем сфокусируйтесь на них, затем с помощью первого щелчка - щелкните <button>, который запускает копию, он должен вернуть истину, но копия не удастся. - person Noitidart; 12.08.2017
comment
@Noitidart Здесь он по-прежнему отлично работает, сосредоточение на инструментах разработчика не остановило его. И, кстати, что будет делать обычный пользователь веб-приложения с инструментами разработчика? - person Tosin John; 12.08.2017
comment
Спасибо @TosinJohn - это очень интересно. Я не знаю, почему у меня выходит из строя первая копия. Большое спасибо за этот тест. Да, правда, их может не быть в инструментах разработчика, но у них может быть два окна рядом друг с другом, и они могут щелкнуть из одного окна в мое веб-приложение (сначала щелкните копию). - person Noitidart; 12.08.2017
comment
команда: clipboardData, setData (Text, text) не копирует форматированный текст, поэтому, например, если вы скопировали текст, содержащий несколько строк (с символами новой строки в качестве разделителей), символ новой строки не будет частью скопированная строка, и вместо этого вы получите одну длинную строку - person shayuna; 04.03.2018
comment
Пользователи пользовательского интерфейса jQuery: обратите внимание, что вы столкнетесь с проблемами при использовании этого метода, если попытаетесь использовать эту функцию из модального диалогового окна. Я подозреваю, что это потому, что модальный интерфейс jQuery UI управляет / манипулирует фокусом документа. Если это соответствует вашему варианту использования, можно сначала закрыть модальное диалоговое окно, а затем скопировать текст. Или просто использовать немодальное диалоговое окно. Я подозреваю, что вы также можете изменить эту функцию, чтобы она добавляла текстовое поле в модальное окно, а не в тело. - person rinogo; 31.12.2018
comment
Я, вероятно, задаю неправильные вопросы в неправильном месте, но все равно хочу попробовать ... можно ли сделать это в виде двух лайнеров, используя какой-то надежный, всегда обновляемый импорт из gitlab или что-то в этом роде? - person cregox; 19.09.2019
comment
нуждается в исправлении, есть отличное средство if, которое проверяет, доступен ли window.clipboardData.setData, но затем, если он проходит, код обходит окно и напрямую попадает в clipboardData! Я добавил код asis в CRA, и он разлетелся, просто нужно окно. приставка - person Andy Lorenz; 16.06.2020

Вот мое мнение об этом ...

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;
}
person nikksan    schedule 14.09.2017
comment
@nikksan, как скопировать строку с \n? - person sof-03; 22.05.2018
comment
@ sof-03 используйте textarea вместо input и добавьте \r\n для разрыва строки - person nikksan; 22.05.2018
comment
Не работает в Microsoft Edge 42.17134.1.0 на Win10x64 - person Honsa Stunna; 30.05.2018
comment
Я скопировал ваш ответ. Он работает в хроме, и это все, что мне нужно. - person user875234; 15.11.2018
comment
Это простейшее решение, которое работает с Firefox v68.0.2 (64-бит). - person Arya; 24.08.2019
comment
По какой-то причине я обычно создаю скрытый ввод или текстовое поле, затем выбираю его, и execCommand не работает, и это было, безусловно, лучшее решение, перечисленное здесь, хотя другие всеобъемлющие и, как и полные страницы википедии, это сработало для меня так что +1 - person Justin; 01.02.2021

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

person bandi    schedule 30.12.2008
comment
Использование флэш-памяти для простой операции копирования кажется излишним, и я рад, что для этого есть чистый JS-способ. А поскольку мы находимся в корпоративной среде. IE в порядке. Спасибо, Банди! - person Eddie; 26.01.2011
comment
пожалуйста, объясните, что делает execCommand(\\’copy\\’);, если не копировать в буфер обмена для IE? @mrBorna - person RozzA; 24.04.2012
comment
Не используйте if(!document.all), но if(!r.execCommand), чтобы никто другой не реализовал это! Document.all к этому не имеет отношения. - person m93a; 15.04.2013
comment
Почему эти проблемы конфиденциальности никогда не возникали в течение десяти лет, когда люди использовали Flash для изменения буфера обмена? И если мы разрешаем только один способ (т.е. копирование, а не чтение его содержимого), как это вызывает беспокойство о конфиденциальности? - person Muhammad bin Yusrat; 06.06.2015
comment
@MuhammadbinYusrat: Хотя это не проблема конфиденциальности, это проблема UX. Представьте, что пользователь что-то скопировал и думает, что он знает, что находится в буфере обмена, затем просматривает ваш сайт, и внезапно в буфере обмена появляется то, о чем он не просил, и он потерял то, что скопировал в первую очередь. - person awe; 02.10.2015

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

person Brent Matzelle    schedule 17.10.2010
comment
Для всех, кто заинтересован, проверьте, что Clippy используется на GitHub при копировании URL-адреса репозитория. - person Radek; 23.05.2011

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

person Richard Shurtz    schedule 03.12.2014
comment
В сообщении блога не упоминается (я надеюсь обновить его в ближайшем будущем), это возможность запускать вырезание и копирование с помощью execCommand. Это поддерживается в IE10 +, Chrome 43+ и Opera29 +. Об этом читайте здесь. updates.html5rocks.com/2015/04/cut-and-copy- команды - person Richard Shurtz; 21.05.2015
comment
Проблема в том, что он перехватывает другие обычные события копирования. - person Brock Adams; 04.02.2017
comment
NB! Это обнюхивание браузера ПЛОХО. Обнюхивайте особенности. Вы затрудняете обновление IE. - person odinho - Velmont; 03.12.2018

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

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

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

person Matthew Scragg    schedule 23.04.2013
comment
Мне он тоже нравится, потому что он короткий. Вы также можете скопировать: <input onclick="this.select(); document.execCommand('copy');" type='text' value='copy me' /> - person Roubi; 28.05.2021

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

});
</script>

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

Примечание. Сейчас это больше не поддерживается. Перейдите на здесь.

person a coder    schedule 11.08.2015
comment
Эта библиотека используется angular.io для его Tour of Hero и отката в изящном режиме для браузера, не поддерживающего execCommand, путем отображения предварительно выбранного текста, который пользователь должен просто скопировать. - person John-Philip; 30.01.2017
comment
Похоже, clipboard.js был заменен или разветвлен, но, похоже, он продолжает жить и активно поддерживается по адресу npmjs .com / package / clipboard. - person Joao; 19.06.2019

Вот как это сделать в 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-адрес страницы.

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

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

person KhoPhi    schedule 06.08.2018
comment
вы связались с localhost - person Joe Warner; 06.08.2018
comment
Имейте в виду, что это не работает в Safari (версия 11.1.2). - person arjunattam; 20.08.2018
comment
@ arjun27 Что ж, надеюсь, когда-нибудь Apple наверстает упущенное. Хотя эта caniuse.com/#feat=clipboard показывает, что упомянутая выше версия частично поддерживается. - person KhoPhi; 20.08.2018
comment
Полезный контент; бесполезное отношение. - person kano; 05.11.2018
comment
Я получаю для обеих функций readText, writeText обещание в отклоненном состоянии - person ramin; 09.12.2018
comment
Согласно предоставленной ссылке, navigator.clipboard поддерживается только для страниц, обслуживаемых через HTTPS. - person TimH - Codidact; 20.12.2018

Я использую это очень успешно (без jQuery или любого другого фреймворка).

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

person Grim    schedule 01.07.2018

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

person Justin    schedule 21.11.2013
comment
кроссбраузерность с Flash? не работает в iOS и Android 4.4 - person Raptor; 27.01.2014
comment
См. Обновленный ответ. Это позволяет меньше шагов для пользователей flash и откат для всех остальных. - person Justin; 27.01.2014
comment
в нем миллиард строк кода. это абсолютно насмешки. лучше вообще этого не делать, чем включать такого монстра в проект - person vsync; 27.10.2014
comment
Существует простая версия gist.github.com/JamesMGreene/8698897, которая не содержит У версии 74k есть все навороты. Ни то, ни другое не очень большое. Я предполагаю, что большинство пользователей согласны с дополнительными миллисекундами, которые потребуются для загрузки файла размером 74 КБ или 20 КБ, поэтому копирование / вставка выполняется одним щелчком мыши вместо двух. - person Justin; 27.10.2014
comment
@Justin Я просто не могу заставить его работать локально, даже если я копирую и вставляю примеры (я вношу минимальные изменения, например, значение src в тегах скрипта). Я считаю, что их документация хороша, но неэффективна. - person Gui Imamura; 23.07.2015

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

person Jeff Baker    schedule 05.11.2015
comment
Спасибо за подведение итогов! В вашем коде есть небольшие ошибки: вы дважды определили переменную диапазона (var range = document.createRange ()). - person Christian Engel; 17.11.2015
comment
Вы правы @ChristianEngel. Я удалил второй. Не знаю, как он туда попал. - person Jeff Baker; 19.11.2015
comment
Привет, Джефф, а что, если я хочу настроить копирование в буфер обмена. Пожалуйста помоги! - person ASHISH KUMAR; 18.06.2021

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

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

person SteamDev    schedule 03.05.2011
comment
jQuery не считается законным ответом на вопрос о JavaScript, поскольку он не только раздут, но и использует ненадежные проприетарные методы Microsoft JScript, такие как innerHTML, которые неправильно регистрируют DOM. - person John; 23.02.2012
comment
92 КБ на самом деле не так уж и много, он работает быстро, и вы можете использовать text() вместо innerHTML(), если хотите .. - person RozzA; 24.04.2012
comment
@John: innerHTML уже давно поддерживается кроссбраузерностью. Тот факт, что Microsoft изначально придумал эту идею, не делает ее ненадежной или несвободной. Он также теперь наконец добавлен в официальную спецификацию (после того, как все основные производители браузеров уже добавили его поддержку ... вздох). - person James M. Greene; 17.01.2013
comment
@John Вы жалуетесь на то, что jQuery недостаточно JavaScripty в ответе, использующем Flash;) - person Max Nanasy; 19.04.2013
comment
Есть много вещей, которые стандартизированы, но не должны. Если вы решите использовать код, который МОЖЕТ работать и НЕ МОЖЕТ, то это ваша игра, а не моя. Люди, которые действительно заботятся о своей работе, всегда будут стремиться улучшить свои навыки, понимание и самих себя, а не оправдывать то, что легко использовать, но также легко сломать. На самом деле, сделать это правильно, используя настоящие стандарты, несложно, и люди могут либо делать что-то прямо сейчас, либо создавать новые неприятности в будущем. - person John; 20.04.2013
comment
innerHTML в большинстве случаев лучше альтернатив. Слезь с высокого коня! Это быстрее, эффективнее и не требует повторного рендеринга страницы. - person Orbiting Eden; 18.06.2013
comment
@RozzA 92KB действительно большой. Пока LTE не созреет GPRS - это WW Mobile стандарт данных, и он начинается с 1 KB/s. Посчитайте сами. - person Tino; 02.08.2013
comment
Вот минималистичное использование библиотеки ZeroClipboard JS: jsfiddle.net/N36uH - person Adrien Be; 18.06.2014
comment
Вот еще два простых примера для начала: jsfiddle.net/c3DUZ и jsfiddle.net/69RLv - person Adrien Be; 18.06.2014
comment
@AdrienBe ни один из ваших примеров не работает для меня ни в Firefox, ни в Chrome - person bhan; 04.04.2015
comment
@AdrienBe Они здесь тоже не работают. На консоли ошибок нет, только предупреждения. Большинство из них из jshint.js - person Gui Imamura; 23.07.2015
comment
@GuiImamura и bhan: извините, ребята, я пока не могу помочь. Попробуйте демонстрацию на странице ZeroClipboard и посмотрите, сможете ли вы использовать этот код для начала. - person Adrien Be; 24.07.2015
comment
Страница, на которую указывает ссылка, теперь мертва, есть только мусор, проверяющий мошенничество. - person MightyPork; 22.03.2016

    $("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.log для функций отладки и / или предупреждений.

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

person SanTasso    schedule 01.06.2020
comment
Нет совместимости с IE - person lance.dolan; 10.11.2020

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

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

person Dominic    schedule 25.07.2017

Другие методы скопируют простой текст в буфер обмена. Чтобы скопировать 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();
person Chase Seibert    schedule 30.12.2008
comment
см. более полное решение HTML здесь stackoverflow.com/questions/34191780/ - person kofifus; 17.12.2015

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

Обработчик нажатия клавиши создает предварительный тег. Мы устанавливаем содержимое для копирования в этот тег, а затем делаем выбор в этом теге и возвращаем 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.

person Enyby    schedule 05.07.2012
comment
Кто-нибудь пробовал это? Звучит как отличная штука, если она действительно работает в разных браузерах! - person Michael; 15.02.2013
comment
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 - НЕИСПРАВНОСТЬ. - person Enyby; 28.02.2013
comment
Для IE нужно запустить фокус на элементе внутри страницы. См. fiddle.jshell.net/H2FHC/3/show и fiddle.jshell.net/H2FHC/3 Работал в IE 9/10. IE 6/7 необходимо обработать выделение другим способом, потому что document.createRange не поддерживается. - person Enyby; 28.02.2013

Этот код протестирован @ 2021 мая. Работайте в Chrome, IE, Edge. Параметр "сообщение" ниже - это строковое значение, которое вы хотите скопировать.

<script type="text/javascript">
    function copyToClipboard(message) {
        var textArea = document.createElement("textarea");
        textArea.value = message;
        textArea.style.opacity = "0"; 
        document.body.appendChild(textArea);
        textArea.focus();
        textArea.select();


        try {
            var successful = document.execCommand('copy');
            var msg = successful ? 'successful' : 'unsuccessful';
            alert('Copying text command was ' + msg);
        } catch (err) {
            alert('Unable to copy value , error : ' + err.message);
        }

        document.body.removeChild(textArea);
    }

</script>
person HO LI Pin    schedule 20.05.2021

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

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

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

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

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

person matthuhiggins    schedule 17.03.2010

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

person Alexandru Sirbu    schedule 25.01.2018

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

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"/>' )
person Bart Burg    schedule 09.07.2015
comment
Как копировать данные прямо из переменной. Т.е. var str = word; ? - person ; 05.02.2016
comment
Сообщение переменной не используется - person Voyager; 25.04.2019
comment
Лучше использовать ‹textarea class = textToCopyInput /› ‹/textarea› в случае, если textToCopy содержит \n - person Voyager; 25.04.2019

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

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

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

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

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

person xiniu    schedule 17.01.2011

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

person Quog    schedule 30.12.2008
comment
Сейчас это устарело ... ознакомьтесь с предложением GvS - person Mottie; 20.09.2009
comment
Предложение от GvS использует флеш-ролик? Разве это не та же идея? - person TheEmirOfGroofunkistan; 08.10.2009

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

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

npm install clipboard --save

А также на Bower

bower install clipboard --save

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

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

Чтобы скопировать выделенный текст («Текст для копирования») в буфер обмена, создайте букмарклет (закладку браузера, которая выполняет 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');
person Mau    schedule 19.10.2017

Это расширение ответа Чейза Зайберта, с тем преимуществом, что он будет работать для элементов 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');
}
person Oliver Bock    schedule 12.08.2011

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

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

person Stormenet    schedule 30.12.2008
comment
Это не мультибраузерность, как запрошено. - person fnkr; 12.05.2013

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

ПРИМЕЧАНИЕ. Этот код будет работать только при выполнении как прямой синхронный код для чего-то вроде метода 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 пиксель на экране в течение миллисекунды, но решил не беспокоиться об этом, и это то, что другие могут решить, если возникнет реальная проблема.

person Community    schedule 14.10.2017

Кажется, я неправильно понял вопрос, но для справки вы можете извлечь диапазон 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;
  }
}
person mrBorna    schedule 16.08.2011
comment
собственно я поправил код. Он работает во всех браузерах, но фактически не копируется в буфер обмена. Просто извлекает (вырезает), клонирует (копирует) контент через переменные. Кажется, я забыл об использовании. - person mrBorna; 17.08.2011

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

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

<p>
    <a onclick="window.clipboardData.setData('text', document.getElementById('Test').innerText);">Copy</a>
</p>
person dvallejo    schedule 13.09.2013
comment
Это не работает в текущих версиях Chrome (V31) или FireFox (v25). Ошибка в том, что window.clipboardData не определено. С другой стороны, это работает в IE9. Итак, пока вы не заботитесь о хороших браузерах и хотите заблокировать свой сайт для использования плохих, это ваш способ сделать это! - person Anthony; 14.11.2013
comment
Я не понимаю, почему так много глупых ответов. w3schools.com/howto/tryit.asp?filename=tryhow_js_copy_clipboard - person Martian2049; 08.02.2018

Мне пришлось скопировать текст без полей ввода (текст в любом теге 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" />
...
person NewToIOS    schedule 09.01.2017

Похоже, вы взяли код из Greasemonkey \ JavaScript Copy to Clipboard button или исходный источник этого фрагмента ...

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

person PhiLho    schedule 30.12.2008
comment
Ключевое слово const относится не к Firefox, а к определенной версии JavaScript, которую не все браузеры реализуют должным образом. - person ProfK; 28.02.2019
comment
@ProfK На момент написания (10 лет назад ...) const был реализован только в Firefox и не был официальным (насколько я помню). Сегодня, конечно, почти все существующие браузеры поддерживают его. - person PhiLho; 26.03.2019

В дополнение к обновленному ответу Дина Тейлора (июль 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();
    }
};
person kosmos    schedule 08.09.2015

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

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

person Yaroslav Yakovlev    schedule 05.10.2015

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

person drzaus    schedule 02.07.2014
comment
Это работает только при вводе в командной строке Chrome. Когда я добавляю его в свой код, функция копирования не определяется. - person EricP; 01.10.2014
comment
@JoeCoder благодарим вас за явное указание на это, поскольку я имел в виду, что это должно быть очевидно из ссылки, но, оглядываясь назад, это не очень очевидно. - person drzaus; 03.10.2014

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

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');
person Alexander Mills    schedule 11.01.2018

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

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

person UserBSS1    schedule 26.06.2013
comment
Вы должны показать здесь несколько примеров кода - псевдокод - это не того, что хотят другие разработчики. В текущем состоянии это не очень хороший ответ. - person Jimbo; 05.08.2013
comment
@Jimbo, решение ниже: для буфера обмена на основе сеанса - person UserBSS1; 07.08.2013
comment
Помните, что сеанс ограничен 5 МБ (afaik). - person StanE; 09.11.2014

Если вы читаете текст из буфера обмена в расширении 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;
}
person supNate    schedule 21.10.2013

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

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

person sinister    schedule 07.05.2015

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

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.log('Copied to clipboard: "'+text+'"');
  }
  catch(e) {
    console.log("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/

person Dino Reic    schedule 13.07.2017

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

copyToClipboard() {
    let el = document.getElementById('Test').innerText
    el.focus(); // el.select();
    try {
        var successful = document.execCommand('copy');
        if (successful) {
            console.log('Copied Successfully! Do whatever you want next');
        }
        else {
            throw ('Unable to copy');
        }
    }
    catch (err) {
        console.warn('Oops, Something went wrong ', err);
    }
}
person Adeel Imran    schedule 19.01.2018
comment
Что здесь ES7? - person Boaz - CorporateShillExchange; 01.03.2018
comment
блок try / catch - person Adeel Imran; 01.03.2018
comment
Если только я не понимаю, что вы имеете в виду, try...catch существует со времен ES3 (то есть около 20 лет назад). - person Boaz - CorporateShillExchange; 01.03.2018
comment
Извините, сэр, это было моим незнанием. Я поправил свой пост. - person Adeel Imran; 01.03.2018

Использование 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>

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

person Alireza    schedule 26.01.2019

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

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.';
    });
}
person VincentPerrin.com    schedule 09.12.2020

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

Cheval

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

person ryanpcmcquen    schedule 10.10.2015

Это автономный класс, который гарантирует невозможность мигания временного 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
    };

})();
person Crashalot    schedule 30.10.2019

Вот простой буфер обмена на основе 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();
        }
    }
?>
person UserBSS1    schedule 06.08.2013
comment
Это единственный ответ здесь, который не требует принуждения браузера к тому, для чего он не предназначен. Твердый +1. - person Luke A. Leber; 09.05.2015

После поиска решения, поддерживающего 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"]);
    });
});
person Mathieu Lescaudron    schedule 25.05.2016

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

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;
}
person mmm    schedule 01.09.2017
comment
textarea.style.position = 'fixed'; будет лучше - person liubiantao; 15.09.2017
comment
@liubiantao, почему это так? - person mmm; 12.09.2020

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

<!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>
person Lars Gross    schedule 19.08.2019

document.querySelector('#some_your_textfield_id').select();
document.execCommand('copy');

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

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

person Игорь Хлебников    schedule 13.10.2020

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

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;
}
person Ritesh Tiwari    schedule 16.12.2020
comment
execCommand теперь считается устаревшим: developer.mozilla.org/en- США / docs / Web / API / Document / execCommand - person Jarede; 12.01.2021

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

person Gruffy    schedule 14.07.2017

Вот элегантное решение для 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;
}
person Chrillewoodz    schedule 26.02.2018

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

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();
}
person Adithya Sai    schedule 05.05.2018

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

person Nishant Singh    schedule 21.11.2018

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

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

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

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

<ul id="dummy_id">
<li>copy content 1 </li>
<li>copy content 2 </li>
<li>copy content 3 </li>
<li>copy content 4 </li>
<li>copy content 5 </li>
</ul>

тогда вызов функции должен быть таким

CopyToNotepad (dummy_id)

Спасибо. Конечно, это может решить вашу проблему!

person Rahul_Daksh    schedule 24.03.2021

person    schedule
comment
Команда execCommand считается устаревшей: developer.mozilla.org/en- США / docs / Web / API / Document / execCommand - person Jarede; 12.01.2021