Этот пост поможет добавить кнопку «Копировать» в элемент html. Он будет работать со всеми типами интерфейсных фреймворков (включая SSR и JAM-стек); основная идея будет такой же, но реализация может отличаться в зависимости от фреймворка.
Начнем с основной логики, то есть с копирования фрагмента текста в буфер обмена.
const copy = async (text) => await navigator.clipboard.writeText(text);
Вот и все !
Этот однострочный файл скопирует любой фрагмент текста с веб-страницы в буфер обмена. Это не ограничивается текстом, вы можете копировать любые произвольные данные, например. изображения в буфер обмена. Более подробную информацию, а также ограничения и поддержку браузера можно найти здесь.
Давайте посмотрим на некоторые варианты использования этого однострочника в реальных сценариях.
Скопируйте код с веб-страницы
Допустим, у вас есть веб-страница, содержащая много кода, и для каждого экземпляра требуется кнопка копирования.
Обычно код пишется внутри тега ‹code› тегом ‹pre›, что может закончиться примерно так.
<pre>
<code>
var message = "Hello world";
console.log(message);
</code>
</pre>
Чтобы разместить кнопку копирования на каждом теге ‹pre›, мы можем использовать следующую логику.
function enableCopy(selector = "pre", childSelector = "code", btnText = "Copy Me", btnTextSuccess = "Copied", activeClass = "--copy") { document.querySelectorAll(`${selector}:not(.${activeClass})`).forEach(node => {
// create a "copy" button let copyBtn = document.createElement("button"); copyBtn.innerText = btnText; // activeClass acts as flag so we don't add another copy button by mistake copyBtn.classList.add(activeClass); node.appendChild(copyBtn);
copyBtn.addEventListener("click", async () => {
// copy to clipboard if (navigator.clipboard) { let text = node.querySelector(childSelector).innerText; await navigator.clipboard.writeText(); }
// change text of button after copying copyBtn.innerText = btnTextSuccess;
// change text back to normal after ### ms setTimeout(() => icon.innerText = btnText, 2000); }) }) }
Что он делает, так это вставляет ‹button› в каждый тег ‹pre›. При его нажатии требуемый текст копируется в буфер обмена.
Чтобы использовать его в нашем случае, просто вызовите метод без параметров; параметры по умолчанию будут работать.
Независимо от того, какой инструмент / библиотеку / фреймворк вы используете, этот подход будет работать.
Реализация как плагин VueJs
Поскольку я пришел из фона VueJs, я буду реализовывать ту же логику, что и плагин VueJS. Основная логика будет такой же, но лучший способ реализации может быть другим. В случае VueJS мы можем использовать плагины и хуки жизненного цикла, чтобы упростить процесс.
Это тот случай, когда шики использовалось для выделения кода. Однако в нем нет функции копировать код. То, как он обертывает код,
<pre class="shiki">
<code>
var message = "Hello world";
console.log(message);
</code>
</pre>
Чтобы добавить кнопку копирования в приведенный выше код, используя тот же подход, что и выше, плагин Vuejs написан следующим образом
// copyPlugin.js
const CopyPlugin = {
// run this method when plugin installs install: function (Vue) { // create a Vue mixin Vue.mixin({ // on each mounted lifecycle hook, run this code mounted: function () { // same function we used above enableCopy("pre.shiki"); } }) } }
export default CopyPlugin;
Затем он импортируется и используется в main.js
файле.
import Vue from "vue"; import CopyPlugin from "./copyPlugin";
Vue.use(CopyPlugin);
Это сделает работу. Единственным дополнительным моментом в этом подходе является обертка основной логики внутри системы плагинов Vuejs. То же самое относится к инструментам react, angular и любым другим. В конце концов, какой бы инструмент мы ни использовали, все сводится к обычным html, css и js.
Этот подход можно расширить, чтобы скопировать текст любого HTML-тега. И текст тоже может быть динамическим (с сервера). Например, вы можете проверить этот пост в блоге. Он такой же, как этот, разница в том, что фрагменты кода выделяются с помощью shiki, а кнопка копирования размещается тем же плагином Vuejs, который описан в этом посте.
Кстати, если вы хотите создавать красивые снимки кода, попробуйте RamroCode 👌