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

2984

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

Я пробовал:

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 получает доступ к буферу пользователя?

  • 0
    Просто любопытно, что вы хотите скопировать в буфер обмена, что пользователь не может сделать самостоятельно?
  • 215
    Ничего особенного. Они могут сделать это самостоятельно, но я хочу предложить также возможность нажатия кнопки, не беспокоясь о выборе правильной части текста.
Показать ещё 5 комментариев
Теги:
copy-paste
clipboard

53 ответа

1763

обзор

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

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

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

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

Async + Fallback

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

Вот простой пример:

function fallbackCopyTextToClipboard(text) {
  var textArea = document.createElement("textarea");
  textArea.value = text;
  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>

Обратите внимание, что этот фрагмент плохо работает во встроенном предварительном просмотре StackOverflow. Вы можете попробовать его здесь: 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( 'копия')

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

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

Поддержка 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 и IE 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 IE 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/catch вызываемый в результате щелчка пользователя, обеспечит вам наибольшую совместимость, используйте следующие условия:

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

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

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

  • 31
    как копировать напрямую из переменных данных .ie: var str = "word"; ?
  • 0
    У меня были некоторые проблемы с queryCommandSupported (), и оказалось, что я вызывал его ДО какого-либо взаимодействия с пользователем. Неправильно: «Вызов метода queryCommandSupported () для вырезки или копирования всегда возвращает false до тех пор, пока пользователь не будет взаимодействовать». (Из ссылки разработчиков Google в ответе).
Показать ещё 46 комментариев
1159

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

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

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

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

<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>
  • 12
    Но существует ограничение на количество символов, отображаемых в этом диалоговом окне, и, таким образом, существует ограничение на количество копируемых данных.
  • 165
    Хороший трюк - но помните, что это Cmd-C для Mac
Показать ещё 24 комментария
226

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

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

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

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

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

  • 6
    Хороший ответ: кросс-браузерная поддержка, обработка ошибок + очистка. Начиная с сегодняшней новой поддержки queryCommandSupported, копирование в буфер обмена теперь возможно в Javascript, и это должен быть принятый ответ, а не неудобный обходной путь 'window.prompt ("Копировать в буфер обмена: Ctrl + C, Enter", text) ". window.clipboardData поддерживается в IE9, поэтому вы должны добавить IE9 в список поддержки браузера, и я думаю, что, возможно, IE8 и предыдущий также, но нужно проверить.
  • 0
    Да уж. IE 8/9 должно быть в порядке. Наше приложение не поддерживает их. Так что я не проверял. IE прекращает поддержку в январе, поэтому я не слишком суетился. Надеюсь, поддержка Safari скоро появится. Я уверен, что это на их радаре.
Показать ещё 12 комментариев
93

Если вам нужно действительно простое решение (требуется менее 5 минут для интеграции) и выглядит хорошо из коробки, то Clippy - отличная альтернатива некоторым более сложным решениям.

Clippy

Это было написано одним из основателей Гитуба. Пример Flash embed code ниже:

<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 для репо.
  • 3
    Хорошо ли работает Clippy с загруженным контентом AJAX? Пытаясь сделать ссылку клиппированной, ее сначала нет на странице. zclip не делает эту работу за меня.
Показать ещё 8 комментариев
84

Чтение и изменение буфера обмена с веб-страницы вызывает проблемы безопасности и конфиденциальности. Однако в 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" />
  • 6
    Использование flash для простой операции копирования кажется излишним, рад, что для этого был чистый JS-способ. И так как мы находимся в корпоративном окружении. IE просто отлично. Спасибо Банди!
  • 4
    execCommand(\\'copy\\'); объясните, что такое execCommand(\\'copy\\'); делает, если не копировать в буфер обмена для IE? @mrBorna
Показать ещё 6 комментариев
66

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

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

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

window.clipboardData

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

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

document.execCommand('copy');

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

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

Вот мое занятие на этом...

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;
 }
  • 0
    @nikksan как скопировать строку с \n ?
  • 0
    @ sof-03 используйте textarea вместо input и добавьте \r\n для перевода строки
Показать ещё 3 комментария
44

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

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

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>

Если вам нужна поддержка без флэш-памяти для iOS, вы просто добавляете fall-back:

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

  • 24
    кросс-браузер с Flash? не работает в iOS и Android 4.4
  • 1
    Смотрите обновленный ответ. Это позволяет меньше шагов для флеш-пользователей и откат для всех остальных.
Показать ещё 3 комментария
25

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

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

  • 0
    jQuery не считается законным ответом на вопрос JavaScript, поскольку он не только раздут, он использует ненадежные проприетарные методы Microsoft JScript, такие как innerHTML, которые неправильно регистрируют DOM.
  • 6
    92 КБ не так уж и велик, он работает быстро, и вы можете использовать text() вместо innerHTML() если хотите ..
Показать ещё 13 комментариев
21

Geesh, не знаю, почему никто еще не указал на это.

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

Используется в моем угловом 6+ коде, например:

<button mat-menu-item (click)="copySomething()">
    <span>Copy link</span>
</button>

Если я передам строку, она копирует ее. Если ничего, копирует URL-адрес страницы.

Более гимнастика в буфер обмена может быть выполнена тоже. Подробнее см. Здесь:

https://developers.google.com/web/updates/2018/03/clipboardapi

  • 0
    вы связались с localhost
  • 1
    Обратите внимание, что это не работает в Safari (версия 11.1.2).
Показать ещё 4 комментария
20

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

В ручном манипуляторе создается тэг 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;

При вставке он создает textarea и работает одинаково.

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

  • 2
    Кто-нибудь пробовал это? Звучит как изящная штука, на случай, если она действительно работает на разных браузерах!
  • 0
    У меня есть шесть месяцев правильной работы в моем заявлении.
Показать ещё 4 комментария
19

Другие методы скопируют обычный текст в буфер обмена. Чтобы скопировать 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();   
  • 2
    +1 r.execCommand ('copy'); отлично работает на FF и IE без Promt!
  • 0
    увидеть более полное решение HTML здесь stackoverflow.com/questions/34191780/…
18

В последнее время Chrome 42+ и Firefox 41+ теперь поддерживают команду document.execCommand('copy'). Таким образом, я создал несколько функций для копирования кросс-браузера в буфер обмена с помощью комбинации старого ответа Tim Down и Ответ разработчика 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-IE
        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 IE 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>
  • 0
    Спасибо за подведение итогов! В вашем коде есть небольшие ошибки: вы дважды определили переменную range (var range = document.createRange ()).
  • 1
    Вы правы @ChristianEngel. Я удалил второй. Я не знаю, как он туда попал.
17

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

  • 0
    Пробелы в этом подходе отсутствуют
  • 1
    Хром. вкладки конвертируются в один пробел
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>
  • 0
    Лучший ответ: D, вы можете улучшить его примерно так: #t {position: absolute; слева: 0; z-индекс: -900; ширина: 0px; высота: 0px; граница: нет; } Так что это будет полностью скрыто! Но на самом деле спасибо, братан!
  • 0
    #t {не изменять размер: нет;}
12

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

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

11

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

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

Скопировать текст из ввода HTML в буфер обмена

 
 function myFunction() {
 /* Получить текстовое поле */
  var copyText = document.getElementById( "myInput" );
 
  /* Выберите текстовое поле */
  copyText.select();

  /* Скопируйте текст внутри текстового поля */
  document.execCommand( "Copy" );
 
  /* Оповещение скопированного текста */
  alert ( "Скопированный текст:" + copyText.value);
 }
 Код>
 
 <! - Текстовое поле - >
 < input type = "text" value = "Hello Friend" id =  "myInput"  >
 
 <! - Кнопка, используемая для копирования текста - >
< button onclick = "myFunction()" > Копировать текст </button>
 Код>

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

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

10

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

  • Использует cssText, чтобы избежать исключений в IE, в отличие от стиля напрямую.
  • Восстанавливает выбор, если он был
  • Устанавливает readonly, поэтому клавиатура не появляется на мобильных устройствах.
  • Обходной путь для 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.
    // 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) {
      return false;
    }
  };
})();
9

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

  • 0
    Это уже устарело ... посмотрите предложение GvS
  • 6
    Предложение GvS использует флэш-фильм? Разве это не та же идея?
Показать ещё 1 комментарий
7

Уже много ответов, но мне нравится добавлять один (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.'); }
7

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

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

npm install clipboard --save

а также на беседке

bower install clipboard --save

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

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

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

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

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

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

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

6

Я нашел еще одно приятное решение LMCButton - небольшая анимационная кнопка перекрестного браузера. Одна функция JavaScript и кнопка swf. Простые варианты (подпись, пользовательский JavaScript).

Ссылка: Скопировать в буфер обмена LMCButton

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

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

Код из 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');
5

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

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

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

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

5

Я тоже хотел бы поделиться своим решением, это немного комбинация между другими ответами.

var copyToClipboard = function(textToCopy){
    $("body")
        .append($('<input type="text" 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($('<input type="text" name="fname" style="opacity: 0;  position: absolute;" class="textToCopyInput"/>' )
  • 0
    Как копировать напрямую из переменных данных .ie: var str = "word"; ?
5

ng-clip было самым простым решением для AngularJS.

5

Мой плохой. Это работает только в IE.

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

<p>
    <a onclick="window.clipboardData.setData('text', document.getElementById('Test').innerText);">Copy</a>
</p>
  • 9
    Это не работает в текущем Chrome (V31) или FireFox (v25). Ошибка в том, что window.clipboardData не определена. С другой стороны, он работает в IE9. Так что, пока вы не заботитесь о хороших браузерах и хотите заблокировать свой сайт на использовании плохих, это способ сделать это!
  • 1
    Да, мой плохой. Мое решение работает только для IE.
Показать ещё 1 комментарий
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;
  }
}
  • 0
    Правильно ли я сказал, что это работает только на IE?
  • 1
    на самом деле я исправил код. Он работает во всех браузерах, но на самом деле не копирует в буфер обмена. Просто извлекает (вырезает), клонирует (копирует) содержимое через переменные. Кажется, я забыл об использовании.
4

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

    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" /" > ...

4

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

Этот код для Greasemonkey, следовательно, небезопасный. И я думаю, синтаксическая ошибка в IE происходит из ключевого слова const, которое относится к Firefox (замените его на var).

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

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

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

  • 0
    Это не мультибраузер, как требуется.
3

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

https://github.com/ryanpcmcquen/cheval

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

3

Обновление 2015: в настоящее время существует возможность использовать document.execCommand для работы с буфером обмена. clipboard.js обеспечивает кросс-браузерный способ работы с буфером обмена (поддержка браузера)

3

По соображениям безопасности вы не можете этого сделать. Вы должны выбрать flash для копирования буфера обмена. Я предлагаю это; http://zeroclipboard.org/

2

Используя функцию 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);
     }
 }
  • 2
    Что такое ES7 здесь?
  • 0
    блок try / catch
Показать ещё 2 комментария
2

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

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

  • 5
    Это работает только при вводе в командной строке Chrome. Когда я добавляю его в свой код, функция копирования не определяется.
  • 0
    @JoeCoder спасибо, что прямо указали на это, как я и имел в виду, чтобы это было видно из ссылки, но в ретроспективе это не очень очевидно.
2

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

@Jimbo, вот простой буфер обмена на основе ajax/session для одного и того же веб-сайта.

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

JS/JQuery

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

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

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

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

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


  });
</script>

html

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

PHP

<?php 
class Ajax extends CI_Controller {
    public function foo_copy($val){
        $this->session->set_userdata(array('clipboard_val' => $val));
    }
    public function foo_paste(){
        echo $this->session->userdata('clipboard_val');
        exit();
    }
}
?>
  • 1
    Это единственный ответ здесь, который не включает принуждение браузера делать что-то, для чего он не предназначен. Твердый +1.
2

Если скопированная ссылка должна быть вставлена ​​на том же сайте, то простым решением будет

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

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

  • 0
    Вы должны показать некоторые примеры кода здесь - псевдокод не то, что хотят другие разработчики. В нынешнем состоянии этот ответ не очень хороший.
  • 0
    @Jimbo, решение ниже: для буфера обмена на основе сессии
Показать ещё 1 комментарий
1

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

Для получения дополнительной информации посетите здесь

  • 0
    Вставить не работает в Chrome.
1

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

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

Просто добавив мои ответы.

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

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

        // Create temp element
        var textarea = doc.createElement('textarea');
        textarea.style.position = 'absolute';
        textarea.style.opacity  = '0';
        textarea.textContent    = text;

        doc.body.appendChild(textarea);

        textarea.focus();
        textarea.setSelectionRange(0, textarea.value.length);

        // copy the selection
        var success;
        try {
                success = doc.execCommand("copy");
        } catch(e) {
                success = false;
        }

        textarea.remove();

        return success;
}
  • 0
    textarea.style.position = 'fixed'; будет лучше
1

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

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

  // all other modern
  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/

1

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

Я использую то же, что и Github: ZeroClipboard

Пример:

http://zeroclipboard.org/index-v1.x.html

HTML

<html>
  <body>
    <button id="copy-button" data-clipboard-text="Copy Me!" title="Click to copy me.">Copy to Clipboard</button>
    <script src="ZeroClipboard.js"></script>
    <script src="main.js"></script>
  </body>
</html>

JS

var client = new ZeroClipboard(document.getElementById("copy-button"));

client.on("ready", function (readyEvent) {
    // alert( "ZeroClipboard SWF is ready!" );

    client.on("aftercopy", function (event) {
        // `this` === `client`
        // `event.target` === the element that was clicked
        event.target.style.display = "none";
        alert("Copied text to clipboard: " + event.data["text/plain"]);
    });
});
0

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

Заметка

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

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

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

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

0

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

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

Здесь элегантное решение для 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;
}
0

Я собрал решение, представленное @dean-taylor, вместе с другим кодом select/unselect из другого места в плагин 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>

Более подробную информацию о методах/событиях можно найти на странице реестра НПМ выше.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню