Xiper

ZeroClipboard — копируем в буфер

Автор: Александр Головко и Егор Скорняков Дата публикации:

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

Где это может применяться? Самое первое, что приходит в голову — копирование программного кода. Например, наведи мышь на любой код у нас на сайте, справа появится кнопочка-иконка «Копировать в буфер». Для чего это нужно? Конечно стандартный вариант — выделить нужный код и нажать Ctrl+С никто не отменял, но выделять фрагмент кода не всегда удобно, а Ctrl+A, естественно, выделит сразу весь текст на странице. В общем, кнопочка, выделяющая нужный текст и сразу отправляющая его в буфер бывает очень кстати.

Проблема в том, что штатными методами HTML+CSS+JS сделать такую кнопку кроссбраузерно крайне затруднительно. Возможность автоматически копировать данные в буфер обмена сознательно исключена во многих современных браузерах. Оно и понятно. Зашел ты на сайт — опа! А у тебя уже в буфере, в лучшем случае, реклама сидит! Или, представь, обратную ситуацию — сайт не записал тебе в буфер, а наоборот, считал оттуда, например, номер кредитки, который ты собирался куда-то вставить. В общем, дыра это в безопасности приличная. Убрали такую возможность, от греха подальше.

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

В качестве варианта, можно использовать ZeroClipboard. Этот скрипт использует тот факт, что, в отличие от HTML+CSS+JS, флеш умеет копировать в буфер обмена. Скрипт создаст прозрачную флешку, полностью повторяющую размеры блока, к которому мы его привяжем (конечно, это будет кнопка «Копировать в буфер»). По нажатию на кнопку (а на самом деле на флешку) и будет осуществляться копирование заданного фрагмента текста в буфер обмена.

Простейший демо-пример — минимальный функционал. Просто вставим в буфер обмена какой-то заранее заданный текст. Более «продвинутый» пример приведен в конце статьи.

Проверено в:

  • IE 7-8
  • Firefox 3.5
  • Opera 10
  • Safari 3

Что качать?

Архив с исходным кодом с официальной страницы ZeroClipboard.

Как правило, из архива тебе понадобится два файла:

  • ZeroClipboard.js — собственно скрипт;
  • ZeroClipboard.swf — флешка.

Быстрый старт

Подключаем ZeroClipboard:

<script type="text/javascript" src="ZeroClipboard.js"></script>

Инициализируем скрипт

<script type="text/javascript">
	var clip = new ZeroClipboard.Client();
    clip.setText('Этот текст окажется в буфере');
    clip.glue('copy_button_ID');
</script>

где:

  • var clip = new ZeroClipboard.Client(); — создаём новый клиент для копирования;
  • clip.setText('текст'); — копируем заданный фрагмент текста;
  • clip.glue('copy_button_ID'); — id элемента, нажатие на который приведет к копированию.

Если файл ZeroClipboard.swf был помещен не в ту папку, в которой находится HTML-страничка, то дополнительно нужно указать путь к этому файлу:

<script type="text/javascript">
	...	
	ZeroClipboard.setMoviePath('path-to/ZeroClipboard.swf');
</script>

А теперь подробнее

В первом примере мы создали clip — клиент для копирования и привязали его к конкретной кнопке. Соответственно, если кнопок у нас несколько, для каждой нужен отдельный клиент.

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

Название функции Описание Пример
setText текст, который будет скопирован в буфер обмена, когда пользователь щелкает на элементе управления clip.setText('текст');
setHandCursor какой курсор показывать при наведении, руку (true — по-умолчанию), стрелку (false) clip.setHandCursor(true);
glue id элемента управления. По его размерам автоматически будет создан и размешен сверху (приклеен) прозрачный флеш-ролик. Подробнее см. ниже. clip.glue('copy_button_ID');
reposition при изменении размера страницы или каких-либо других манипуляциях, в результате которых элемент, к которому приклеилась флешка мог «переехать», нужно обновить и позицию флешки. Типичное место использования reposition() — обработчик события window.onresize clip.reposition();
hide скрыть флешку — позволяет, при необходимости, временно отключить возможность копирования clip.hide();
show показать флешку — действие, обратное hide. Автоматически вызывает и reposition(), что очень логично — за время отсутствия флешки, кнопка могла «переехать» clip.show();
setCSSEffects разрешает (true — по-умолчанию) или запрещает (false) эмуляцию эффектов hover и active. Подробнее, см. ниже. lip.setCSSEffects(false);
getHTML предназначен для того, чтобы не клеить флешку к существующему элементу, а создать флешку саму по себе. Возвращает элемент object/embed с заданными размерами. var html = clip.getHTML(60, 60);
addEventListener позволяет задать функции-обработчики некоторых событий. Первый аргумент — название события, второй — имя пользовательской функции. Подробнее, см. ниже. clip.addEventListener( 'onLoad', my_load_handler );
destroy удаляет объект клиента копирования, а так же саму флешку из DOM clip.destroy();

Позиционирование

На официальном сайте плагина настоятельно рекомендуют помещать элемент управления, к которому нужно подклеивать флешку, в дополнительный контейнер div с заданным для него position:relative. В этом случае, обещается «более точное позиционирование флешки» — в общем-то это логично.

На деле будет выглядеть, например, так:

<div id="copyButtonСontainer">
	<button id="copyButton">Копировать в буфер</button>
</div>

В этом случае, вклеить флешку нужно с помощью варианта функции glue с двумя аргументами. Первым идет id кнопки, вторым — id контейнера:

<script language="JavaScript">
	var clip = new ZeroClipboard.Client();
    clip.setText('Этот текст окажется в буфере');
    clip.glue('copy_button_ID', 'copyButtonСontainer');
</script>

Примечание. В этом случае функция reposition() работать не будет (собственно, она уже и не понадобится).

Эмуляция эффектов hover и active

Флешка, находясь выше (по z-оси) элемента управления, естественно, «подгребает» под себя события, связанные с мышью. Это значит, в частности, и то, что псевдоклассы :hover и :active для нашей кнопки станут нерабочими. Разрулить эту ситуацию призвана функция setCSSEffects. Если для клиента был произведен вызов setCSSEffects(true), то включается эмуляция CSS-эффектов. Это означает, что к элементу управления будут в нужный момент добавляться/убираться классы hover и active. Тебе остается только позаботиться о нужных стилях, например:

#copy_button_ID.hover {
	border:1px dashed #060;
}
#copy_button_ID.hover {
	border:1px solid #060;
}

События

С помощью функции addEventListener можно добавить обработку таких событий:

Название события Описание Пример
onLoad функция вызывается когда флешка загружена, и полностью готова к использованию clip.addEventListener('onLoad', my_load_handler);
onMouseOver наведение курсора мыши clip.addEventListener('onMouseOver', my_mouse_over_handler);
onMouseOut уход курсора мыши clip.addEventListener('onMouseOut', my_mouse_out_handler);
onMouseDown нажатие кнопки мыши над флешкой clip.addEventListener('onMouseDown', my_mouse_down_handler);
onMouseUp отпускание кнопки мыши над флешкой clip.addEventListener('onMouseUp', my_mouse_up_handler);
onComplete текст был удачно скопирован в буфер clip.addEventListener('onComplete', my_complete);
onMouseUp отпускание кнопки мыши над флешкой clip.addEventListener('onMouseUp', my_mouse_up_handler);

Пример использования события:

 clip.addEventListener( 'onMouseOver', my_mouse_over_handler );
function my_mouse_over_handler( client ) {
	alert( "мышь над флешкой!" );
}

Более сложный демо-пример. Копируем в буфер содержимое тега div. Используем CSS-эффекты.

Проверено в:

  • IE 7-8
  • Firefox 3.5
  • Opera 10
  • Safari 3

Материалы

  • Документация к zeroclipboard.