Часто встречаются сайты, на которых можно скопировать текст при помощи специальной кнопки. Для качественной вёрстки страниц я обычно применяю набор инструментов от Twitter Bootstrap 5, новая версия которого успешно выпущена и полностью готова к полноценной разработке. В этом наборе не хватает только выше упомянутой кнопки, но её можно реализовать используя код на JavaScript.
Разработчики Bootstrap в новом решении надумали отказаться от библиотеки jQuery, поэтому я напишу код на чистом JS. Для всплывающих подсказок применю модуль Tooltips «из коробки», а также добавлю для красоты немного иконок из набора «Bootstrap Icons».
Разметка HTML
В минимальном исполнении разметку можно выполнить так:
<div class="copy-clipboard text-center text-muted m-auto">
<span>Скопировать эту строку</span><button title="Скопировать" class="btn btn-outline-secondary btn-sm shadow-none ms-3">Кнопка</button>
</div>
Здесь важно указать контейнеру класс .copy-clipboard
, а внутри него расположить строку <span>
и кнопку <button>
. При нажатии на кнопку строка будет скопирована в буфер обмена (Clipboard).
Примечание:
размножать необходимо именно контейнеры<div>
с классом.copy-clipboard
Код JavaScript
Теперь создадим непосредственно сам код, который отвечает за всю процедуру копирования.
Пример:
let copyList = document.querySelectorAll( '.copy-clipboard' );
let copyArray = Array.prototype.slice.call( copyList );
function tooltipUpdate( button, tooltip, title ) {
tooltip.dispose();
button.setAttribute( 'title', title );
tooltip = new bootstrap.Tooltip( button );
tooltip.show();
return tooltip;
}
copyArray.map( function ( copy ) {
let text = copy.querySelector( 'span' ).innerText;
let button = copy.querySelector( 'button' );
let tooltip = new bootstrap.Tooltip( button );
button.addEventListener( 'mouseover', function () {
tooltip = tooltipUpdate( button, tooltip, 'Скопировать' );
} );
button.addEventListener( 'click', function () {
window.navigator.clipboard.writeText( text );
tooltip = tooltipUpdate( button, tooltip, 'Готово!' );
} );
} );
Ранее для копирования текста применялась функция document.execCommand('copy')
. Она устарела, официально не поддерживается, но многие сайты продолжают её использовать. Особенность функции в том, что кроме поля <input>
она ничего не могла скопировать и приходилось интерактивно создавать это поле, помещать в него текст, а затем удалять.
Теперь можно применить конструкцию window.navigator.clipboard.writeText(text)
для копирования текста напрямую из других тегов, таких как <span>
, <p>
, <div>
и др.
Посмотрите упрощённый пример по ссылке.
Пример Bootstrap 5 и Tooltips
Приведу практический пример разметки для Twitter Bootstrap 5. Здесь подключены различные библиотеки для наведения красоты, но все они из линейки продуктов Bootstrap. В коде есть небольшие изменения: вместо кнопки используется иконка <i>
, а в остальном – просто более наглядный вариант.
Интерактивный пример можно посмотреть по данной ссылке.
<!doctype html>
<html lang="ru" class="h-100">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/css/bootstrap.min.css" integrity="sha256-z8OR40MowJ8GgK6P89Y+hiJK5+cclzFHzLhFQLL92bg=" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.5.0/font/bootstrap-icons.css" integrity="sha256-PDJQdTN7dolQWDASIoBVrjkuOEaI137FI15sqI3Oxu8=" crossorigin="anonymous">
<title>Пример копирования текста с применением Twitter Bootstrap 5 Tooltips | onstartup.ru</title>
</head>
<body class="d-flex h-100 bg-light">
<div class="container m-auto">
<div class="row justify-content-center">
<div class="col-auto">
<div class="card shadow">
<div class="card-header text-center">
<h1 class="display-6">Пример копирования текста<br>Twitter Bootstrap 5 Tooltips</h1>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-borderless mb-0">
<tbody>
<tr>
<th scope="row">ПРИМЕР 1:</th>
<td>
<div class="copy-clipboard d-flex justify-content-between">
<span class="lead h5">Скопировать строку 1</span><i class="bi bi-clipboard-plus btn p-1 pt-0" data-bs-toggle="tooltip" title="Скопировать"></i>
</div>
</td>
</tr>
<tr>
<th scope="row">ПРИМЕР 2:</th>
<td>
<div class="copy-clipboard d-flex justify-content-between">
<span class="lead h5">Скопировать строку 2</span><i class="bi bi-clipboard-plus btn p-1 pt-0" data-bs-toggle="tooltip" title="Скопировать"></i>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/js/bootstrap.bundle.min.js" integrity="sha256-KuvCVS19rfTjoLgMyDDCdOkRRlhNrY4psEM4uezts2M=" crossorigin="anonymous"></script>
<script>
let copyList = document.querySelectorAll( '.copy-clipboard' );
let copyArray = Array.prototype.slice.call( copyList );
function tooltipUpdate( button, tooltip, title ) {
tooltip.dispose();
button.setAttribute( 'title', title );
tooltip = new bootstrap.Tooltip( button );
tooltip.show();
return tooltip;
}
copyArray.map( function ( copy ) {
let text = copy.querySelector( 'span' ).innerText;
let button = copy.querySelector( 'i' );
let tooltip = new bootstrap.Tooltip( button );
button.addEventListener( 'mouseover', function () {
tooltip = tooltipUpdate( button, tooltip, 'Скопировать' );
this.classList.remove( 'bi-clipboard-check' );
this.classList.add( 'bi-clipboard-plus' );
} );
button.addEventListener( 'click', function () {
window.navigator.clipboard.writeText( text );
tooltip = tooltipUpdate( button, tooltip, 'Готово!' );
this.classList.remove( 'bi-clipboard-plus' );
this.classList.add( 'bi-clipboard-check' );
} );
} );
</script>
</body>
</html>
Узнайте о том, как подключить Bootstrap к WordPress через CDN.
Uncaught TypeError: window.navigator.clipboard is undefined
<anonymous> http://а....а.com/js/bootstrap.bundle.min.js:30
bootstrap.bundle.min.js:30:3
Ошибка карты кода: Error: request failed with status 404
URL ресурса: http://а....а.com/js/bootstrap.bundle.min.js
URL карты кода: bootstrap.bundle.min.js.map
Строка 30-я не срабатывает из этого блока window.navigator.clipboard.writeText( text );
button.addEventListener( 'click', function () {
window.navigator.clipboard.writeText( text );
tooltip = tooltipUpdate( button, tooltip, 'Copied' );
this.classList.remove( 'bi-clipboard-plus' );
this.classList.add( 'bi-clipboard-check' );
} );