JavaScript - Копирование в буфер с помощью Clipboard.js

Содержание:
  1. clipboard.js - js скрипт для копирования текста в буфер
  2. Основы работы с clipboard.js
  3. Дополнительные возможности clipboard.js
  4. Комментарии

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

clipboard.js - js скрипт для копирования текста в буфер

Clipboard.js – это современный скрипт, который используется для того чтобы предоставить пользователю возможность более просто скопировать (например, с помощью нажатия на кнопку) некоторую информацию представленную на странице сайта в буфер обмена. Работа данного скрипта опирается на API Selection and execCommand.

JavaScript - Копирование в буфер обмена (скрипт clipboard.js)

Демо Скачать clipboard.js

Скрипт работает в браузерах Chrome 42+, Firefox 41+, IE 9+ Opera 29+, Safari 8.

Преимущества скрипта clipboard.js:

  • Не требует для своей работы Flash (как например ZeroClipboard).
  • Не имеет зависимостей, т.е. не требует для своей работы наличие подключенной библиотеки jQuery.
  • Имеет очень маленький размер.

Основы работы с clipboard.js

Основные действия при работе со скриптом clipboard.js (копирование в буфер) представим в виде следующих действий:

  1. Скачать zip-архив, распаковать его и скопировать файл clipboard.min.js в необходимый каталог на сайте.

  2. Подключить файл clipboard.min.js к необходимым страницам на сайте.

    <script src="путь/до/clipboard.min.js"></script>

  3. Инициализировать Clipboard для необходимых элементов на странице, посредством передачи ему DOM-селектора, HTML-элемента или списка, состоящего из HTML-элементов. Т.е. необходимо функции-конструктору Clipboard передать элементы, при нажатии на которые информация будет копироваться в буфер.

    Например, инициализируем Clipboard для всех элементов на странице имеющих класс .btn-clipboard.

    <script>new Clipboard('.btn-clipboard');
    </script>
  4. Добавить атрибуты data-* инициализированным HTML элементам.

    Рассмотрим следующие варианты:

    1. Копирование текста из другого элемента

    <!-- Цель - элемент, содержимое которого необходимо скопировать (указываем id, например example1) -->
    <pre id="example1">
    ....
    </pre>
    <!-- Кнопка, при нажатии на которую, происходит копирование цели. Цель указывается с помощью атрибута data-clipboard-target -->
    <button class="btn-clipboard" data-clipboard-target="#example1">
      Скопировать в буфер обмена
    </button>

    2. Вырезать текст из другого элемента

    <pre id="example2">
    ....
    </pre>
    <!-- Для вырезания контента необходимо дополнительно указывать атрибут data-clipboard-action со значением cut -->
    <button class="btn-clipboard" data-clipboard-target="#example2">
       Скопировать в буфер обмена
    </button>

    3. Копирование в буфер текста из атрибута

    <!-- Кнопка, при нажатии на которую будет скопирован текст, находящийся в атрибуте data-clipboard-text -->
    <button class="btn-clipboard" data-clipboard-text="...">
      Скопировать в буфер обмена
    </button>

Пример создания кнопки, предназначенной для копирования информации в буфер

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

<!-- Цель (structurePage) - элемент, содержимое которого нужно скопировать -->
<pre id="structurePage">
  <!DOCTYPE html>
  <html>
  <head>
    <meta charset="utf-8">
    <title>Пример HTML5 страницы</title>
  </head>
  <body>
    Содержимое страницы...
  </body>
  </html>
</pre>
<!-- Триггер - элемент, при нажатии на который будет скопирована цель -->
<!-- В триггере цель устанавливается с помощью значения атрибута data-clipboard-target -->
<button type="button" data-clipboard-target="#structurePage">Скопировать код</button>

<!-- Подключаем скрипт clipboard.min.js -->
<script src="clipboard.min.js"></script>
<script>
// Инициализируем элемент button для всех элементов button, расположенных после pre
new Clipboard('pre+button');
</script>
JavaScript - скопировать содержимое элемента pre в буфер обмена
JavaScript - скопировать содержимое элемента pre в буфер обмена

Дополнительные возможности clipboard.js

Рассмотрим основные возможности, которые предоставляет js-скрипт clipboard.js.

События clipboard.js

Действия при копировании информации в буфер можно отслеживать с помощью событий clipboard.js. Всего доступно 2 события. Первое событие (success) происходит после успешного копирования, а второе (error) возникает в случае ошибки (неудачи).

var clipboard = new Clipboard('.btn');
clipboard.on('success', function(e) {
  console.info('Действие:', e.action);
  console.info('Текст:', e.text);
  console.info('Триггер:', e.trigger);
  e.clearSelection();
});
clipboard.on('error', function(e) {
  console.error('Действие:', e.action);
  console.error('Триггер:', e.trigger);
});

Указание источника копирования с помощью функции

Clipboard.js позволяет указывать цель (элемент, содержимое которого необходимо скопировать или текст) не только с помощью data-атрибутов, но и динамически с помощью функции. Это позволяет не вносить изменения в Ваш код HTML, т.е. избавляет Вас от необходимости добавлять к элементам атрибуты data и id.

Рассмотрим это на следующих примерах:

1. Динамическое установление цели (target).

// инициализируем Clipboard для всех элементов на странице, имеющих класс .btn-clipbboard
new Clipboard('.btn-clipboard', {
  // цель определяем с помощью функции. Она должна возращать необходимый элемент (например, следующий после инициированного)
  // цель - это элемент, содержимое которого необходимо скопировать.
  target: function(trigger) {
    return trigger.nextElementSibling;
  }
});

2. Динамическое установление текста.

// инициализируем Clipboard для всех элементов на странице, имеющих класс .btn-clipbboard
new Clipboard('.btn-clipboard', {
  // текст определяем с помощью функции (например, значение атрибута  aria-label)
  text: function(trigger) {
    return trigger.getAttribute('aria-label');
  }
});

Примеры, использующие дополнительные возможности clipboard.js

Рассмотрим несколько примеров, в которых будем использовать дополнительные возможности, которые предлагает скрипт clipboard.js.

1. Пример динамического создания кнопок копирования для всех элементов pre на странице.

Рассмотрим пример, в котором с помощью кода JavaScript добавим кнопки ко всем элементам pre на странице для копирования соответствующего кода.

//после загрузки страницы
window.addEventListener('load', function() {
  // получить коллекцию элементов pre на странице
  var pre = document.getElementsByTagName('pre');
  // перебрать все элементы pre с помощью цикла for
  for (var i=0; i<pre.length; i++) {
    // создать контейнер div
    var divClipboard = document.createElement('div');
    // добавить к контейнеру div класс .bd-clipboard
    divClipboard.className = 'bd-clipboard';
    // создать элемент span (кнопку Копировать)
    var button = document.createElement('span');
    // добавить к элементу span класс .btn-clipboard
    button.className = 'btn-clipboard';
    // элементу span установить контент Копировать
    button.textContent = 'Копировать';
    // добавить элемент span в качестве дочернего к элементу div
    divClipboard.appendChild(button);
    // добавить элемент div перед pre
    pre[i].parentElement.insertBefore(divClipboard,pre[i]);
  }
  // инициализируем Clipboard для каждой кнопки
  var btnClipboard = new Clipboard('.btn-clipboard', {
    target: function(trigger) {
      console.log(trigger.parentElement.nextElementSibling);
      trigger.clearSelection;
      return trigger.parentElement.nextElementSibling;
    }
  });
  btnClipboard.on('success', function(e) {
    e.clearSelection();
  });
});
<p>HTML:</p>
<pre>
<p>Некоторый текст</p>
</pre>
<p>CSS:</p>
<pre>
/* CSS */
p {
  font-size: 16px;
  font-weight: bold;
}
</pre>
.bd-clipboard {
  position: relative;
  display: none;
}
@media (min-width: 768px) {
  .bd-clipboard {
    display: block;
  }
}
.btn-clipboard {
  position: absolute;
  top: 8px;
  right: 8px;
  z-index: 10;
  display: block;
  padding: 4px 8px;
  font-size: 12px;
  color: #818a91;
  cursor: pointer;
  background-color: transparent;
  border-radius: 4px;
}
.bd-clipboard+pre{
  margin-top:0;
}
.btn-clipboard:hover {
  color:#fff;
  background-color:#027de7
}
Кнопки, добавленные ко всем HTML элементам pre на странице с помощью JavaScript
Добавление кнопок к pre элементам
Поднесение курсора к тексту копировать
Изменение изображения надписи копировать при поднесении к ней курсора

2. Пример, в котором будем использовать события clipboard.js для создания интерактивности процесса копирования в буфер.

Рассмотрим пример, в котором будем обрабатывать действия пользователя после того как он нажал на кнопку, выполняющей копирования информации в буфер. Если копирование информации в буфер прошло успешно, то изменим (на 3 секунды) текст кнопки на контент "Скопировано". В противном случае, если произошла ошибка при копировании, то изменим (тоже на 3 секунды) текст кнопки на "Нажмите Ctrl+C для копирования".

// при успешном копировании
btnClipboard.on('success', function(event) {
  // убираем выделение
  event.clearSelection();
  // изменяем текст триггера на Скопировано
  event.trigger.textContent = 'Скопировано';
  // Возращаем через 3 секунды текст триггеру на Копировать
  window.setTimeout(function() {
    event.trigger.textContent = 'Копировать';
  }, 3000);
});
// если копирование завершилось с ошибкой
btnClipboard.on('error', function(event) {
  // изменяем текст кнопки
  event.trigger.textContent = 'Нажмите "Ctrl + C" для копирования';
  // через 3 секунды возвращаем кнопки текст "Копировать"
  window.setTimeout(function() {
    event.trigger.textContent = 'Копировать';
  }, 3000);
});

Комментарии: 11

Михаил
Михаил
Здравствуйте,
кнопка появилась, но не копирует, где искать проблему?
Подключал по примеру 1
«1. Пример динамического создания кнопок копирования для всех элементов pre на странице.»
Интерактивность тоже не сработала.
clipboard.min.js загружал на сервер и через
< script  src = " https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.0/clipboard.min.js " > </ script >
Александр Мальцев
Александр Мальцев
Здравствуйте, в этой статье используется первая версия этого скрипта. Скачать clipboard.js v.1.7.1 можно по этой ссылке. Посмотреть демку можно здесь.

Во второй версии необходимо вместо класса Clipboard использовать ClipboardJS.
Михаил
Михаил
Спасибо,
v.1.7.1 пошла, а вторая так и не запустилась. Интерактивности тоже нет, видимо не так подключаю, потом еще попробую.
Ivan
Ivan
Здравствуйте! Благодарю за статью. Попробовал — рабочий. Но есть трудности, к примеру, при создании таблицы, если в одном td находится тег pre и соответственно закрывающий, то в другом td, где кнопка, которая должна была копировать содержание из первого td не работает, не копирует. Как это можно исправить? Благодарю за ответ
Александр Мальцев
Александр Мальцев
Здравствуйте, спасибо. Чтобы это сделать, вам необходимо указать цель (pre) относительно кнопки.
Например, если таблица имеет вид:
<table>
<tr>
  <td>
    <pre><p>Строка 1</p><p>Строка 2</p></pre>
  </td>
  <td>
    <button class="copy">Copy</button>
  </td>
</tr>
<tr>
  <td>
    <pre><p>Строка 3</p></pre>
  </td>
  <td>
    <button class="copy">Copy</button>
  </td>
</tr>
</table>
То, код будет следующий:
<script>
window.addEventListener('load', function() {
  var btnClipboard = new Clipboard('.copy', {
    target: function(trigger) {
      // ищем цель относительно кнопки:
      // .copy -> td (родитель) -> tr (родитель) -> pre (ищем в tr элемент pre)
      return trigger.parentElement.parentElement.getElementsByTagName('pre')[0];
    }
  });
  btnClipboard.on('success', function(e) {
    e.clearSelection();
  });
});
</script>
Дмитрий
Дмитрий
Добрый день! Спасибо за статью, скажите, когда я нажимаю на кнопку «копировать» текст копируется с пустой областью и если вставить то текст вставляется на строчку ниже, как это исправить?
Александр Мальцев
Александр Мальцев
Здравствуйте. Попробуйте удалить пробельные символы слева и справа, например, с помощью функции trim().
Аноним
Аноним
сорри
Аноним
Аноним
Добрый день!
Вконтакте например, если у вас в буффере изображение сохранено и вы нажимайте на ctrl+v в посте, то сайт начинает этот файл аплоадить.

Вы знайте как такую штуку реализовать?
Александр Мальцев
Александр Мальцев
Аноним
Аноним
Да, Js вы знайте отлично! Спасибо)