"Скопировать в буфер обмена" - функционал, который мы все используем несколько раз на дню, но клиентские API имеют свои недостатки; некоторые из них выводят раздражающее окошко с вопросом «Вы уверены?» всякий раз при попытке что-то скопировать, а это не очень хорошо отражается на юзабилити и общей картине приложения или сайта.
Несколько лет назад я рассказывал о ZeroClipboard - скрипта, позволяющего копировать в буфер обмена с помощью Flash. Я знаю, мы все ненавидим Flash, но функциональность превыше всего, и, надо признать, - это было достойное решение. Теперь, у нас есть кое-что получше: библиотека clipboard.js, не требующая Flash, наличия фреймворка типа jQuery и работающая во всех современных браузерах:
Установка clipboard.js
Вы можете установить ее с помощью npm или bower:
npm install clipboard --save
bower install clipboard --save
Если у вас не установлены менеджеры пакетов, скачайте ZIP-файл у нас или с официального сайта.
Подключение clipboard.js
Во-первых, подключите скрипт, расположенный d папке dist или загрузите его из CDN перед закрывающим тегом body:
<script src="dist/clipboard.min.js"></script>
Теперь вам нужно создать его экземпляр, передавая DOM-селектор, HTML элемент, или список HTML-элементов.
new Clipboard('.btn');
Внутри нам нужно собрать все элементы, которые совпадают с нашим селектором и присоединить приемники событий каждому из них. Но знаете что? Если у вас будет, к примеру, сто совпадающих элементов, эта операция может потреблять много памяти. Именно поэтому мы будем использовать передачу событий, которая заменяет множественные приемники событий одним. В конце концов, #perfmatters.
Примеры копирования в буфер обмена
Скажем красиво: мы живем в эпоху декларативного ренессанса, поэтому мы решили воспользоваться всеми преимуществами HTML5-атрибутов data для лучшего юзабилити.
Копирование текста из другого элемента
Довольно часто требуется скопировать содержимого из другого элемента. Вы можете сделать это, добавив атрибут data-clipboard-target
в ваш триггер-элемент. Значение, которое вы включаете в данный атрибут, должно совпадать с селектором другого элемента.
<!-- Ссылка -->
<input id="foo" value="https://github.com/zenorocha/clipboard.js.git">
<!-- Триггер -->
<button class="btn" data-clipboard-target="#foo">
<img src="assets/clippy.svg" alt="Скопировать в буфер">
</button>
Вырезать текст из другого элемента
Кроме того, вы можете определить атрибут data-clipboard-action
, чтобы указать хотите вы copy
(скопировать) или cut
(скопировать и вырезать) контекст. Если опустить этот атрибут, будет использоваться copy
.
<!-- Ссылка -->
<textarea id="bar">Mussum ipsum cacilds...</textarea>
<!-- Триггер -->
<button class="btn" data-clipboard-action="cut" data-clipboard-target="#bar">
Скопировать и вырезать
</button>
Как вы можете ожидать, действие cut
работает только на элементах <input> или <textarea>.
Копирование текста из атрибута
На самом деле нам даже не нужен другой элемент, чтобы копировать из него содержимое. Можно просто включить атрибут data-clipboard-text
в триггерный элемент.
<!-- Триггер -->
<button class="btn" data-clipboard-text="Копируем без FLASH">
Скопировать в буфер
</button>
События
Бывают случаи, когда вам нужно осуществить обратную связь с пользователем или сохранить то, что было выбрано после операции копирования/вырезания. Именно поэтому сначала обрабатываются пользовательские события, такие как 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);
});
Для наглядной демонстрации откройте консоль :)
Дополнительные функции
Если вы не хотите изменять ваш HTML-код, - для вас есть очень удобный API. Все, что вам нужно сделать, - это объявить функцию, делать свое дело, и вернуть значение. Например, если вы хотите динамически устанавливать target
, вам необходимо вернуть узел:
new Clipboard('.btn', {
target: function(trigger) {
return trigger.nextElementSibling;
}
});
Если вы хотите динамически устанавливать text
, вы должны вернуть строку:
new Clipboard('.btn', {
text: function(trigger) {
return trigger.getAttribute('aria-label');
}
});
Кроме того, если вы работаете с одностраничным приложением (SPA), вы можете управлять жизненным циклом DOM более точно. Вот как очистить события и объекты, которые мы создаем:
var clipboard = new Clipboard('.btn');
clipboard.destroy();
Никакого Flash, простое API и работает во всех основных браузерах! Все это делает clipboard.js привлекательным для web-разработчиков. Дни подтормаживающего Flash сочтены – да здравствуют веб-технологии!