Задача: для удобства сотрудников сделать копирование артикула по клику.
Реализовывать мы будем это на стороне клиента (браузера) при помощи JavaScript используя нужные нам методы при работе с DOM.
Давайте рассуждать. У нас есть артикул, значение которого выводится в строчном элементе <span>
, благодаря атрибуту class мы можем «зацепиться за него» — это, условно говоря, его имя.
Так как нам нужно только его значение, отметим для себя элемент span с классом «sku»
Нам нужно его выдернуть из DOM (Объектная Модель Документа) и в этом нам поможет метод querySelector()
Согласитесь, что нашего элемента может на странице и не существовать, поэтому нужно проверить его существование. Если совпадений не будет найдено, то наш метод вернёт значение null
.
Давайте реализуем эту логику в виде кода.
const sku = document.querySelector(".sku");
if(sku !== null){
console.log(sku);
}
Если вы всё сделали правильно, то непременно увидите в консоли этот выбранный элемент:
Следующим логическим шагом нам нужно будет отследить событие клика по этому элементу. В этом нам поможет метод
addEventListener() который будет обрабатывать событие клика по этому элементу
const sku = document.querySelector(".sku");
if (sku !== null) {
sku.addEventListener("click", (e) => {
});
}
Итак, событие клика мы отслеживаем и теперь настало время вызвать в момент клика нашу функцию, которая и будет осуществлять копирование содержимого.
Функцию назовём copyWooSKU()
Что должно находиться в функции? Очевидно, что нам нужно получить (зачитать) значение артикула, а затем его каким то чудесным образом скопировать в буфер обмена пользователя. Реализовывать мы это будем через современный API Async Clipboard (на замену синхронного метода document.execCommand())
Clipboard API предоставляет возможность реагировать на команды буфера обмена (вырезать, копировать и вставить), а также выполнять асинхронные чтение/запись в системный буфер обмена.
https://developer.mozilla.org/en-US/docs/Web/API/Clipboard_API
Итак, нам понадобится:
- Объект
Navigator
- Свойство этого объекта .clipboard — которое используется для чтения и записи содержимого буфера обмена
- И метод writeText() — для записи текста в буфер обмена
async function copyWooSKU(txt) {
try {
await navigator.clipboard.writeText(txt);
} catch (error) {
console.error("Ошибочка вышла: ", error);
}
}
const sku = document.querySelector(".sku");
if (sku !== null) {
sku.addEventListener("click", (e) => {
copyWooSKU(e.target.innerText);
});
}
Ну вот и всё! Это должно работать 🙂
Обращу внимание, что стрелочные функции не имеют собственного контекста this. То есть в стрелочных функциях
e.currentTarget != this
Комментарий к коду:
- async перед функцией, потому что в теле функции есть await и вернётся промис
- try / catch для обработки исключения
- e.target.innerText — это извлечение значения свойства (текста в нашем случае) элемента по которому кликаем
Как и многие новые API, API буфера обмена поддерживается только для страниц, обслуживаемых по протоколу HTTPS. Чтобы предотвратить злоупотребления, доступ к буферу обмена разрешен только тогда, когда страница является активной вкладкой. Страницы на активных вкладках могут записывать в буфер обмена без запроса разрешения, но чтение из буфера обмена всегда требует разрешения.
Учтите, что метод writeText() ожидает безопасного контекста HTTPS и если ваше соединение осуществляется по схеме протокола HTTP то может вылететь как раз таки ошибочка 🙂
Рекомендуется для чтения:
Разблокирование доступа к буферу обмена
Как добавить уведомление?
Очевидно, что в момент клика непонятно, произошло копирование или нет. Если улучшать наш код для пользователя, то по доброму необходимо сделать уведомление, чтобы клиенту было понятно, что копирование осуществилось.
Давайте рассуждать. Нам нужно методами JavaScript создать элемент в котором будет содержаться текст нашего уведомления. После вызова функции необходимо отобразить это уведомление и спустя пару секунд скрыть. Весь наш код теперь выглядит следующим образом:
async function copyWooSKU(txt) {
try {
await navigator.clipboard.writeText(txt);
} catch (error) {
console.error("Ошибочка вышла: ", error);
}
}
const sku = document.querySelector(".sku");
if (sku !== null) {
sku.addEventListener("click", (e) => {
e.preventDefault();
copyWooSKU(e.target.innerText);
const myNotice = document.createElement("span");
myNotice.style.color = "red";
myNotice.innerText = "Скопировано";
// селектор родителя
if (sku.parentElement) {
const parentElement = sku.parentElement;
parentElement.appendChild(myNotice);
window.setTimeout(function () {
parentElement.removeChild(myNotice);
}, 2000);
} // TODO else
});
}
В этом коде использован следующий JavaScript:
- Метод preventDefault () — добавил на всякий случай для отмены обработки клика (до нашего обработчика)
- document.createElement() — метод для создания элемента
- style.color — присваиваем CSS-свойство для изменения цвета шрифта
- Свойство .innerText — позволяет задавать текст нашему созданному элементу
- Метод .appendChild() добавляет узел в конец списка дочерних элементов указанного родительского узла. Будьте внимательны! Селектор родительского элемента у вас может отличаться.
- Функция .setTimeout() — для задержки выполнения
- Метод .removeChild() удаляет дочерний элемент из DOM.
- parentElement это родительский элемент текущего узла.
Возможно некоторые свойства, такие как : target, innerText станут понятнее, если мы на них взглянем. Для этого в этом отрезке кода, где мы отслеживаем действие по клику, можно вывести в консоль это событие клика мышкой:
if (sku !== null) {
sku.addEventListener("click", (e) =>
console.log(e);
});
}
Мы увидим объект, и именно в нём и находятся наши свойства:
А вот свойство со значением артикула, к которому мы обращаемся
Поиграть с рабочим кодом можно тут