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

3326

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

Я пытался:

function copyToClipboard(text) {
    if (window.clipboardData) { // Internet Explorer
        window.clipboardData.setData("Text", text);
    } else {  
        unsafeWindow.netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");  
        const clipboardHelper = Components.classes["@mozilla.org/widget/clipboardhelper;1"].getService(Components.interfaces.nsIClipboardHelper);  
        clipboardHelper.copyString(text);
    }
}

но в Internet Explorer выдает синтаксическую ошибку. В Firefox сказано unsafeWindow is not defined.

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

Сантьяго Корредойра
источник
Просто любопытно, что вы хотите скопировать в буфер обмена, что пользователь не может сделать сам?
scunliffe
233
Ничего особенного. Они могут сделать это самостоятельно, но я хочу предложить также возможность нажатия кнопки, не беспокоясь о выборе правильной части текста.
Сантьяго Корредойра
4
Это длинное сообщение в блоге содержит множество способов сделать это: Доступ к системному буферу обмена с помощью JavaScript - Святой Грааль?
Аарон Дигулла
Это дает браузеру неопределенное исключение в IE, а также в FF
Jagadeesh
1
Если мы можем поместить текст в буфер обмена пользователя, мы можем испортить его буфер обмена.
Фрэнк Фанг,

Ответы:

2252

обзор

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

  1. Async Clipboard API [navigator.clipboard.writeText]
    • Текстовая часть доступна в Chrome 66 (март 2018)
    • Доступ асинхронный и использует обещания JavaScript , может быть написан таким образом, чтобы запросы безопасности пользователя (если отображаются) не прерывали JavaScript на странице.
    • Текст может быть скопирован в буфер обмена непосредственно из переменной.
    • Поддерживается только на страницах, обслуживаемых по HTTPS.
    • В Chrome 66 страниц в активных вкладках можно записывать в буфер обмена без запроса разрешения.
  2. document.execCommand('copy')
    • Большинство браузеров поддерживают это по состоянию на апрель 2015 года (см. «Поддержка браузеров» ниже).
    • Доступ является синхронным, то есть останавливает JavaScript на странице до завершения, включая отображение и взаимодействие пользователя с любыми запросами безопасности.
    • Текст читается из DOM и помещается в буфер обмена.
    • Во время тестирования ~ апреля 2015 года только Internet Explorer был отмечен как отображающий запросы разрешений при записи в буфер обмена.
  3. Переопределение события копирования
    • См. Документацию API буфера обмена по переопределению события копирования .
    • Позволяет изменить то, что появляется в буфере обмена из любого события копирования, может включать в себя другие форматы данных, кроме обычного текста.
    • Здесь не рассматривается, так как это не дает прямого ответа на вопрос.

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

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

ВАЖНО (отмечено здесь 2020/02/20)

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

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

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

Async + Fallback

Из-за уровня поддержки браузера для нового Async Clipboard API вы, вероятно, захотите использовать этот document.execCommand('copy')метод, чтобы получить хорошее покрытие браузера.

Вот простой пример (может не работать, встроенный в этот сайт, прочитайте «важное» примечание выше):

function fallbackCopyTextToClipboard(text) {
  var textArea = document.createElement("textarea");
  textArea.value = text;
  
  // Avoid scrolling to bottom
  textArea.style.top = "0";
  textArea.style.left = "0";
  textArea.style.position = "fixed";

  document.body.appendChild(textArea);
  textArea.focus();
  textArea.select();

  try {
    var successful = document.execCommand('copy');
    var msg = successful ? 'successful' : 'unsuccessful';
    console.log('Fallback: Copying text command was ' + msg);
  } catch (err) {
    console.error('Fallback: Oops, unable to copy', err);
  }

  document.body.removeChild(textArea);
}
function copyTextToClipboard(text) {
  if (!navigator.clipboard) {
    fallbackCopyTextToClipboard(text);
    return;
  }
  navigator.clipboard.writeText(text).then(function() {
    console.log('Async: Copying to clipboard was successful!');
  }, function(err) {
    console.error('Async: Could not copy text: ', err);
  });
}

var copyBobBtn = document.querySelector('.js-copy-bob-btn'),
  copyJaneBtn = document.querySelector('.js-copy-jane-btn');

copyBobBtn.addEventListener('click', function(event) {
  copyTextToClipboard('Bob');
});


copyJaneBtn.addEventListener('click', function(event) {
  copyTextToClipboard('Jane');
});
<div style="display:inline-block; vertical-align:top;">
  <button class="js-copy-bob-btn">Set clipboard to BOB</button><br /><br />
  <button class="js-copy-jane-btn">Set clipboard to JANE</button>
</div>
<div style="display:inline-block;">
  <textarea class="js-test-textarea" cols="35" rows="4">Try pasting into here to see what you have on your clipboard:

  </textarea>
</div>

(пример codepen.io может не работать, прочитайте «важное» примечание выше). Обратите внимание, что этот фрагмент плохо работает во встроенном предварительном просмотре Stack Overflow, вы можете попробовать его здесь: https://codepen.io/DeanMarkTaylor/pen/RMRaJX?editors = 1011

Async Clipboard API

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

var text = "Example text to appear on clipboard";
navigator.clipboard.writeText(text).then(function() {
  console.log('Async: Copying to clipboard was successful!');
}, function(err) {
  console.error('Async: Could not copy text: ', err);
});

document.execCommand ( 'копия')

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

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

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

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

(может не работать встроенным в этот сайт, прочитайте "важное" примечание выше)

var copyTextareaBtn = document.querySelector('.js-textareacopybtn');

copyTextareaBtn.addEventListener('click', function(event) {
  var copyTextarea = document.querySelector('.js-copytextarea');
  copyTextarea.focus();
  copyTextarea.select();

  try {
    var successful = document.execCommand('copy');
    var msg = successful ? 'successful' : 'unsuccessful';
    console.log('Copying text command was ' + msg);
  } catch (err) {
    console.log('Oops, unable to copy');
  }
});
<p>
  <button class="js-textareacopybtn" style="vertical-align:top;">Copy Textarea</button>
  <textarea class="js-copytextarea">Hello I'm some text</textarea>
</p>

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

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

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

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

(может не работать встроенным в этот сайт, прочитайте "важное" примечание выше)

function copyTextToClipboard(text) {
  var textArea = document.createElement("textarea");

  //
  // *** This styling is an extra step which is likely not required. ***
  //
  // Why is it here? To ensure:
  // 1. the element is able to have focus and selection.
  // 2. if element was to flash render it has minimal visual impact.
  // 3. less flakyness with selection and copying which **might** occur if
  //    the textarea element is not visible.
  //
  // The likelihood is the element won't even render, not even a
  // flash, so some of these are just precautions. However in
  // Internet Explorer the element is visible whilst the popup
  // box asking the user for permission for the web page to
  // copy to the clipboard.
  //

  // Place in top-left corner of screen regardless of scroll position.
  textArea.style.position = 'fixed';
  textArea.style.top = 0;
  textArea.style.left = 0;

  // Ensure it has a small width and height. Setting to 1px / 1em
  // doesn't work as this gives a negative w/h on some browsers.
  textArea.style.width = '2em';
  textArea.style.height = '2em';

  // We don't need padding, reducing the size if it does flash render.
  textArea.style.padding = 0;

  // Clean up any borders.
  textArea.style.border = 'none';
  textArea.style.outline = 'none';
  textArea.style.boxShadow = 'none';

  // Avoid flash of white box if rendered for any reason.
  textArea.style.background = 'transparent';


  textArea.value = text;

  document.body.appendChild(textArea);
  textArea.focus();
  textArea.select();

  try {
    var successful = document.execCommand('copy');
    var msg = successful ? 'successful' : 'unsuccessful';
    console.log('Copying text command was ' + msg);
  } catch (err) {
    console.log('Oops, unable to copy');
  }

  document.body.removeChild(textArea);
}


var copyBobBtn = document.querySelector('.js-copy-bob-btn'),
  copyJaneBtn = document.querySelector('.js-copy-jane-btn');

copyBobBtn.addEventListener('click', function(event) {
  copyTextToClipboard('Bob');
});


copyJaneBtn.addEventListener('click', function(event) {
  copyTextToClipboard('Jane');
});
<div style="display:inline-block; vertical-align:top;">
  <button class="js-copy-bob-btn">Set clipboard to BOB</button><br /><br />
  <button class="js-copy-jane-btn">Set clipboard to JANE</button>
</div>
<div style="display:inline-block;">
  <textarea class="js-test-textarea" cols="35" rows="4">Try pasting into here to see what you have on your clipboard:

  </textarea>
</div>

Дополнительные замечания

Работает только в том случае, если пользователь выполняет действие

Все document.execCommand('copy')вызовы должны происходить как прямой результат действия пользователя, например, обработчик события 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')обернутого в try/ catchblock, вызываемый в результате щелчка пользователя, обеспечит вам наибольшую совместимость, используйте следующие условия:

Любой вызов document.execCommand, document.queryCommandSupportedили document.queryCommandEnabledдолжен быть завернут в try/ catchблоке.

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

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

Дин Тейлор
источник
41
как скопировать непосредственно с переменным .ie данных: var str = "word";?
jscripter
10
@BubuDaba Создайте фиктивный файл, скрытый <textarea>с помощью JS, добавьте его document.body, задайте его значение для переменной и используйте его в темпе copyTextarea, затем удалите его сразу после копирования содержимого.
SeinopSys
3
Есть ли что-то для Safari или какие-либо показатели того, что это будет реализовано в Safari?
www139
3
Единственная найденная версия, которая работает во всех браузерах. Я обнаружил, что при использовании этого в Boostrap Modal мне пришлось добавить текстовую область к модальному. Я бы дал +1000, если бы мог за ваше решение !!! СПАСИБО!
Патрик
3
@AyaSalama ключевой момент заключается в том, что действие «копировать» не может иметь место, если браузеру не выполнено это действие. Пользователь не сможет выполнить действие, если элемент имеет стиль «display: none», поскольку он не сможет ни увидеть его, ни взаимодействовать с ним.
Дин Тейлор,
1258

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

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>

Ярек Милевски
источник
91
Умно, но это поддерживает только одну строку.
Арам Кочарян
61
Тривиально изменить функцию «prompt» на пользовательский модальный режим. Основная хитрость заключается в том, чтобы использовать редактируемое поле содержимого и предварительно выбирать текст, и чтобы он не нарушал пользовательский интерфейс браузера, заставляя пользователя принимать Действуй сам. A ++
Jon z
110
до сих пор не использует JavaScript для копирования в буфер обмена ^ _ ^
RozzA
23
Если ваш текст содержит более 2000 символов, он будет усечен, но для небольших текстовых примеров он отлично работает
RasTheDestroyer
445
Странно, что это получает 457 голосов, но не отвечает на вопрос: скопируйте в буфер обмена в Javascript !
Stevenvh
300

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

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

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

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

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

Грег Лоу
источник
9
Хороший ответ: кросс-браузерная поддержка, обработка ошибок + очистка. Начиная с сегодняшней новой поддержки queryCommandSupported, копирование в буфер обмена теперь возможно в Javascript, и это должен быть принятый ответ, а не неуклюжий обходной путь «window.prompt (« Копировать в буфер обмена: Ctrl + C, Enter », text)». window.clipboardData поддерживается в IE9, поэтому вы должны добавить IE9 в список поддержки браузера, и я думаю, что, возможно, IE8 и предыдущий также, но нужно проверить.
user627283
Да. IE 8/9 должно быть в порядке. Наше приложение не поддерживает их. Так что я не проверял. IE прекращает поддержку в январе, так что я не слишком суетился. Надеюсь, поддержка Safari скоро появится. Я уверен, что это на их радаре.
Грег Лоу
4
@SantiagoCorredoira: В 2016 году это заслуживает того, чтобы быть принятым ответом. Пожалуйста, рассмотрите возможность переназначения BGT (большой зеленый тик).
Лоуренс Дол
3
@Noitidart Я протестировал, и он отлично работает для Firefox 54, Chrome 60 и Edge Browser, даже если фокус не находится в HTML-документе, ваша ошибка, вероятно, специфична для версии FF 55
Tosin John
2
@Noitidart Это все еще отлично работает здесь, сосредоточение на инструментах разработки не остановило это. И, между прочим, что будет делать обычный пользователь веб-приложения на инструментах разработчика
Tosin John
97

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

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: обратите внимание, что использование inputполя html не будет учитывать разрывы строк \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
источник
@nikksan как скопировать строку с \n?
Соф-03
2
@ sof-03 используйте textarea вместо input и добавьте \r\nразрыв строки
nikksan
1
Не работает в Microsoft Edge 42.17134.1.0 на Win10x64
Хонса Стунна
3
Я скопировал ваш ответ. Он работает в Chrome, и это все, что мне нужно.
user875234
Это самое простое решение, которое работает с Firefox v68.0.2 (64-разрядная версия).
Арья
88

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

Брент Мацель
источник
12
Для всех, кто интересуется, отметьте использование Clippy на GitHub при копировании URL для репо.
Радек
66
К вашему сведению, использование Clippy на GitHub было заменено ZeroClipboard.
Джеймс М. Грин
219
ОП хотел найти решение в JavaScript. Не флеш.
МТ.
21
@MT, под «javascript» некоторые люди подразумевают «в клиенте браузера», поэтому, хотя JS-only может быть требованием, многие из людей, которые случайно ответят на этот вопрос, действительно ищут JS или другой широко поддерживаемый. клиент-тек. Flash не работает на всех платформах, но для такой дополнительной функции, как поддержка буфера обмена, стоит добавить, если он улучшает UX по сравнению с всплывающим диалогом (что, безусловно, и делает).
Дейв Допсон,
13
Теперь полагаться на Flash означает, что вещи не работают для процента посетителей сайта, что недопустимо почти для всех, кто занимается веб-разработкой.
Jinglesthula
86

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

банди
источник
7
Использование flash для простой операции копирования кажется излишним, рад, что для этого был чистый JS-способ. И так как мы находимся в корпоративном окружении. IE просто отлично. Спасибо Банди!
Эдди
5
Пожалуйста, объясните, что execCommand(\\’copy\\’);делает, если не скопировать в буфер обмена для IE? @mrBorna
RozzA
20
Не используйте, if(!document.all)но if(!r.execCommand)никто другой не реализует это! Document.all абсолютно не имеет к этому отношения.
m93a
1
Чувак, это то, что мне нравится в простом и чистом коде, он работает почти всегда с незначительным обслуживанием. Это сделало это для меня, Это прекрасно работает.
Самуэль Рамзан
1
не работает в последних версиях Chrome, Firefox или MS Edge :(
Джонатан Марзулло
69

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

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

var isIe = (navigator.userAgent.toLowerCase().indexOf("msie") != -1 
           || navigator.userAgent.toLowerCase().indexOf("trident") != -1);

document.addEventListener('copy', function(e) {
    var textToPutOnClipboard = "This is some text";
    if (isIe) {
        window.clipboardData.setData('Text', textToPutOnClipboard);    
    } else {
        e.clipboardData.setData('text/plain', textToPutOnClipboard);
    }
    e.preventDefault();
});

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

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

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

window.clipboardData

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

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

document.execCommand('copy');

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

Ричард Шурц
источник
2
Не упоминается в сообщении в блоге (я надеюсь обновить его в ближайшем будущем), есть возможность запуска вырезать и копировать с помощью execCommand. Это поддерживается в IE10 +, Chrome 43+ и Opera29 +. Читайте об этом здесь. updates.html5rocks.com/2015/04/cut-and-copy-commands
Ричард Шурц
Проблема в том, что он перехватывает другие обычные события копирования.
Брок Адамс
NB! Этот браузер нюхает плохо. Сделайте фича нюхания. Вы затрудняете обновление IE.
Одино - Велмонт
51

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 .

Примечание. Это устарело. Мигрируй сюда .

кодер
источник
Эта библиотека используется angular.io для Tour of Hero и аварийного режима в изящном режиме для браузера, который не поддерживает execCommand, отображая предварительно выбранный текст, который пользователь только что скопировал.
Джон-Филипп
1
Похоже, что clipboard.js был заменен или разветвлен, но, похоже, он работает и активно поддерживается по адресу npmjs.com/package/clipboard
Joao
35

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

Джастин
источник
25
кросс-браузер с Flash? не работает в iOS и Android 4.4
Raptor
1
Смотрите обновленный ответ. Это позволяет меньше шагов для флеш-пользователей и откат для всех остальных.
Джастин
8
у него есть миллиард строк кода. это просто насмешки. лучше вообще не делать этого, чем включать такого монстра в проект
vsync
2
Существует простая версия gist.github.com/JamesMGreene/8698897, которая составляет 20 КБ и не имеет всех наворотов в версии 74 КБ. Ни один не очень большой. Я предполагаю, что большинство пользователей согласны с дополнительными миллисекундами, которые будут занимать загружаемый файл размером 74 КБ или 20 КБ, поэтому копирование / вставка выполняется одним щелчком мыши вместо двух.
Джастин
@ Просто я не могу заставить его работать локально, даже если я копирую и вставляю примеры (я делаю минимальные изменения, например, значение srcв тегах скрипта). Я чувствую, что их документация хороша, но неэффективна.
Гуй Имамура
29

В 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 страницы.

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

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

KhoPhi
источник
Вы связались с localhost
Джо Уорнер
2
Обратите внимание, что это не работает в Safari (версия 11.1.2)
arjun27
1
@ arjun27 Ну, надеюсь, когда-нибудь Apple догонит. Хотя на этом caniuse.com/#feat=clipboard показана упомянутая выше версия, которая частично поддерживается.
Хофи
2
Я получаю для обеих функций readText, writeText Promise в отклоненном состоянии
ramin
3
Согласно предоставленной ссылке, «navigator.clipboard поддерживается только для страниц, обслуживаемых по HTTPS»
TimH - Codidact
26

В одном из проектов, над которым я работал, плагин jQuery для копирования в буфер обмена, использующий библиотеку Zero Clipboard .

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

SteamDev
источник
6
92kb на самом деле не такой уж большой, он работает быстро, и вы можете использовать text()его, innerHTML()если хотите…
RozzA
17
@John: innerHTMLкросс-браузер уже давно поддерживается. Просто потому, что Microsoft изначально пришла в голову идея, она не делает ее ненадежной или проприетарной. Это также теперь наконец добавлено к официальной спецификации (после того, как каждый крупный поставщик браузера уже добавил поддержку для этого ... вздох ).
Джеймс М. Грин
19
@John Вы жалуетесь на то, что jQuery недостаточно JavaScripty в ответе, использующем Flash;)
Макс Нанаси
4
innerHTML лучше, чем альтернативы в большинстве случаев. Слезь со своей высокой лошади! Это быстрее, эффективнее и не требует перерисовки страницы.
орбите Эдема
4
@RozzA 92KBдействительно большой. Пока LTE не станет зрелым, GPRS является стандартом мобильной передачи данных WW , и он начинается с 1 KB/s. Сделай математику сам.
Тино
23

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

function selectElementContents(el) {
    // Copy textarea, pre, div, etc.
    if (document.body.createTextRange) {
        // IE
        var textRange = document.body.createTextRange();
        textRange.moveToElementText(el);
        textRange.select();
        textRange.execCommand("Copy");
    } 
    else if (window.getSelection && document.createRange) {
        // Non-Internet Explorer
        var range = document.createRange();
        range.selectNodeContents(el);
        var sel = window.getSelection();
        sel.removeAllRanges();
        sel.addRange(range);
        try {
            var successful = document.execCommand('copy');
            var msg = successful ? 'successful' : 'unsuccessful';
            console.log('Copy command was ' + msg);
        }
        catch (err) {
            console.log('Oops, unable to copy');
        }
    }
} // end function selectElementContents(el)

function make_copy_button(el) {
    var copy_btn = document.createElement('input');
    copy_btn.type = "button";
    el.parentNode.insertBefore(copy_btn, el.nextSibling);
    copy_btn.onclick = function() {
        selectElementContents(el);
    };

    if (document.queryCommandSupported("copy") || parseInt(navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./)[2]) >= 42) {
        // Copy works with Internet Explorer 4+, Chrome 42+, Firefox 41+, Opera 29+
        copy_btn.value = "Copy to Clipboard";
    }
    else {
        // Select only for Safari and older Chrome, Firefox and Opera
        copy_btn.value = "Select All (then press Ctrl + C to Copy)";
    }
}
/* Note: document.queryCommandSupported("copy") should return "true" on browsers that support copy
    but there was a bug in Chrome versions 42 to 47 that makes it return "false".  So in those
    versions of Chrome feature detection does not work!
    See https://code.google.com/p/chromium/issues/detail?id=476508
*/

make_copy_button(document.getElementById("markup"));
<pre id="markup">
  Text that can be copied or selected with cross browser support.
</pre>

Джефф Бейкер
источник
Спасибо за подведение итогов! В вашем коде есть небольшие ошибки: вы дважды определили переменную range (var range = document.createRange ()).
Кристиан Энгель
1
Вы правы @ChristianEngel. Я удалил второй. Я не знаю, как он туда попал.
Джефф Бейкер
23

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

зловещий
источник
Пробелы в этом подходе отсутствуют
Бикрам
1
Хром. вкладки преобразуются в один пробел
Бикрам
22

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

Обработчик нажатия клавиш создает тег «pre». Мы устанавливаем содержимое для копирования в этот тег, затем выбираем этот тег и возвращаем true в обработчике. Это вызывает стандартный обработчик хрома и копирует выделенный текст.

И если вам нужно, вы можете установить тайм-аут для функции для восстановления предыдущего выбора. Моя реализация на Mootools:

   function EnybyClipboard() {
     this.saveSelection = false;
     this.callback = false;
     this.pastedText = false;

     this.restoreSelection = function() {
       if (this.saveSelection) {
         window.getSelection().removeAllRanges();
         for (var i = 0; i < this.saveSelection.length; i++) {
           window.getSelection().addRange(this.saveSelection[i]);
         }
         this.saveSelection = false;
       }
     };

     this.copyText = function(text) {
       var div = $('special_copy');
       if (!div) {
         div = new Element('pre', {
           'id': 'special_copy',
           'style': 'opacity: 0;position: absolute;top: -10000px;right: 0;'
         });
         div.injectInside(document.body);
       }
       div.set('text', text);
       if (document.createRange) {
         var rng = document.createRange();
         rng.selectNodeContents(div);
         this.saveSelection = [];
         var selection = window.getSelection();
         for (var i = 0; i < selection.rangeCount; i++) {
           this.saveSelection[i] = selection.getRangeAt(i);
         }
         window.getSelection().removeAllRanges();
         window.getSelection().addRange(rng);
         setTimeout(this.restoreSelection.bind(this), 100);
       } else return alert('Copy not work. :(');
     };

     this.getPastedText = function() {
       if (!this.pastedText) alert('Nothing to paste. :(');
       return this.pastedText;
     };

     this.pasteText = function(callback) {
       var div = $('special_paste');
       if (!div) {
         div = new Element('textarea', {
           'id': 'special_paste',
           'style': 'opacity: 0;position: absolute;top: -10000px;right: 0;'
         });
         div.injectInside(document.body);
         div.addEvent('keyup', function() {
           if (this.callback) {
             this.pastedText = $('special_paste').get('value');
             this.callback.call(null, this.pastedText);
             this.callback = false;
             this.pastedText = false;
             setTimeout(this.restoreSelection.bind(this), 100);
           }
         }.bind(this));
       }
       div.set('value', '');
       if (document.createRange) {
         var rng = document.createRange();
         rng.selectNodeContents(div);
         this.saveSelection = [];
         var selection = window.getSelection();
         for (var i = 0; i < selection.rangeCount; i++) {
           this.saveSelection[i] = selection.getRangeAt(i);
         }
         window.getSelection().removeAllRanges();
         window.getSelection().addRange(rng);
         div.focus();
         this.callback = callback;
       } else return alert('Fail to paste. :(');
     };
   }

Применение:

enyby_clip = new EnybyClipboard(); //init 

enyby_clip.copyText('some_text'); // place this in CTRL+C handler and return true;

enyby_clip.pasteText(function callback(pasted_text) {
        alert(pasted_text);
}); // place this in CTRL+V handler and return true;

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

PS может быть это решение может быть использовано для создания полностью кросс-браузерного решения без флеш-памяти. Работает в FF и Chrome.

Enyby
источник
2
Кто-нибудь пробовал это? Звучит как изящная штука, на случай, если она действительно работает на разных браузерах!
Майкл
1
jsfiddle.net/H2FHC Демонстрация: fiddle.jshell.net/H2FHC/show Пожалуйста, откройте его и нажмите Ctrl + V или Ctrl + C. В FF 19.0 вилки отлично. В Chrome 25.0.1364.97 м тоже. Опера 12,14 - ОК. Safari 5.1.7 для Windows - ОК. IE - FAIL.
Enyby
Для IE нужно запустить фокус на элементе внутри страницы. См. Fiddle.jshell.net/H2FHC/3/show и fiddle.jshell.net/H2FHC/3 Работает в IE 9/10. IE 6/7 требует процесса создания выделения другим способом, поскольку document.createRange не поддерживается.
Enyby
21

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

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

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

  • Использует cssText, чтобы избежать исключений в Internet Explorer, в отличие от стиля напрямую.
  • Восстанавливает выбор, если он был
  • Устанавливает только чтение, чтобы клавиатура не появлялась на мобильных устройствах
  • Есть обходной путь для iOS, чтобы он действительно работал, как обычно, блокирует execCommand.

Вот:

const copyToClipboard = (function initClipboardText() {
  const textarea = document.createElement('textarea');

  // Move it off screen.
  textarea.style.cssText = 'position: absolute; left: -99999em';

  // Set to readonly to prevent mobile devices opening a keyboard when
  // text is .select()'ed.
  textarea.setAttribute('readonly', true);

  document.body.appendChild(textarea);

  return function setClipboardText(text) {
    textarea.value = text;

    // Check if there is any content selected previously.
    const selected = document.getSelection().rangeCount > 0 ?
      document.getSelection().getRangeAt(0) : false;

    // iOS Safari blocks programmtic execCommand copying normally, without this hack.
    // /programming/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')

Dominic
источник
13

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

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

matthuhiggins
источник
12

  <!DOCTYPE html>

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

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

  <textarea id=t></textarea>

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

Сэмюэл Тис
источник
Лучший ответ: D, вы можете улучшить его примерно так: #t {position: absolute; слева: 0; z-индекс: -900; ширина: 0px; высота: 0px; граница: нет; } Так что это будет полностью скрыто! Но на самом деле спасибо, братан!
Федерико Наваррете
#t {resize: none;}
SmartManoj
Объяснение будет в порядке.
Питер Мортенсен
12

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

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

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

Александру сирбу
источник
11

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

Это что-то вроде комбинации между другими ответами.

var copyToClipboard = function(textToCopy){
    $("body")
        .append($('<textarea name="fname" class="textToCopyInput"/>' )
        .val(textToCopy))
        .find(".textToCopyInput")
        .select();
      try {
        var successful = document.execCommand('copy');
        var msg = successful ? 'successful' : 'unsuccessful';
        alert('Text copied to clipboard!');
      } catch (err) {
          window.prompt("To copy the text to clipboard: Ctrl+C, Enter", textToCopy);
      }
     $(".textToCopyInput").remove();
}

Он использует JQuery, но это не обязательно, конечно. Вы можете изменить это, если хотите. Я просто имел в своем распоряжении jQuery. Вы также можете добавить немного CSS, чтобы убедиться, что ввод не отображается. Например что-то вроде:

.textToCopyInput{opacity: 0; position: absolute;}

Или, конечно, вы могли бы также сделать некоторые встроенные стили

.append($('<textarea name="fname" style="opacity: 0;  position: absolute;" class="textToCopyInput"/>' )
Барт Бург
источник
Как копировать напрямую из переменных данных .ie: var str = "word"; ?
Переменная msg не используется
Voyager
Лучше использовать '<textarea class = "textToCopyInput" /> </ textarea>', если он textToCopyсодержит\n
Voyager,
8

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

Quog
источник
Это уже устарело ... посмотрите предложение GvS
Mottie
6
Предложение GvS использует флэш-фильм? Разве это не та же идея?
TheEmirOfGroofunkistan
8

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

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

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

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

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

xiniu
источник
7

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

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

npm install clipboard --save

А также на Bower

bower install clipboard --save

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

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

Это расширение ответа @ Chase с тем преимуществом, что оно будет работать для элементов IMAGE и TABLE, а не только для DIV в IE9.

if (document.createRange) {
    // IE9 and modern browsers
    var r = document.createRange();
    r.setStartBefore(to_copy);
    r.setEndAfter(to_copy);
    r.selectNode(to_copy);
    var sel = window.getSelection();
    sel.addRange(r);
    document.execCommand('Copy');  // does nothing on FF
} else {
    // IE 8 and earlier.  This stuff won't work on IE9.
    // (unless forced into a backward compatibility mode,
    // or selecting plain divs, not img or table). 
    var r = document.body.createTextRange();
    r.moveToElementText(to_copy);
    r.select()
    r.execCommand('Copy');
}
Оливер Бок
источник
5

Кажется, я неправильно понял вопрос, но для справки вы можете извлечь диапазон DOM (не для буфера обмена; совместим со всеми современными браузерами) и объединить его с событиями oncopy, onpaste и onbeforepaste, чтобы получить поведение буфера обмена. Вот код для достижения этого:

function clipBoard(sCommand) {
  var oRange=contentDocument.createRange();
  oRange.setStart(startNode, startOffset);
  oRange.setEnd(endNode, endOffset);
/* This is where the actual selection happens.
in the above, startNode and endNode are dom nodes defining the beginning 
and end of the "selection" respectively. startOffset and endOffset are 
constants that are defined as follows:

END_TO_END: 2
END_TO_START: 3
NODE_AFTER: 1
NODE_BEFORE: 0
NODE_BEFORE_AND_AFTER: 2
NODE_INSIDE: 3
START_TO_END: 1
START_TO_START: 0

and would be used like oRange.START_TO_END */
      switch(sCommand) {
    case "cut":
          this.oFragment=oRange.extractContents();
      oRange.collapse();
      break;
    case "copy":
      this.oFragment=oRange.cloneContents();
      break;
    case "paste":
      oRange.deleteContents();
      var cloneFragment=this.oFragment.cloneNode(true)
      oRange.insertNode(cloneFragment);
      oRange.collapse();
      break;
  }
}
mrBorna
источник
1
на самом деле я исправил код. Он работает во всех браузерах, но на самом деле не копирует в буфер обмена. Просто извлекает (вырезает), клонирует (копирует) содержимое через переменные. Кажется, я забыл об использовании.
mrBorna
5

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

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

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

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

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

Питер Мортенсен
источник
5

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