Заметка: кнопка «Копировать ссылку на товар»
Кнопка Копировать позволяет скопировать в буфер обмена готовую HTML-ссылку на товар (со всеми атрибутами) для последующей вставки в форум, блог или другую форму сайта.
Скопированная ссылка содержит:
текст — полное название товара,
атрибут
title— рекламную фразу с призывом купить,URL товара.
Благодаря экранированию специальных символов (прежде всего двойных кавычек " в атрибутах) готовая ссылка не «ломает» HTML страницы, куда её вставляют.
Ниже приведён полный код кнопки с подробными комментариями.
<!-- Кнопка копирования ссылки на товар -->
<button class="btn btn-primary copy-btn"
onclick="copyProductLink(this)"
data-title="{PHP|htmlspecialchars({PHP.item.fieldmrkt_title})}"
data-metatitle="{PHP|htmlspecialchars({PHP.item.fieldmrkt_metatitle})}"
data-url="{PHP.cfg.mainurl}/{PHP.item.fieldmrkt_pageurl}"
data-bs-toggle="tooltip"
data-bs-placement="top"
data-bs-title="{PHP.langSkStr.tools_copy_link_title}">
{PHP.langSkStr.tools_copy_link}
</button>
<script>
function copyProductLink(btn) {
// Получаем данные из data-атрибутов кнопки.
// Благодаря htmlspecialchars в шаблоне кавычки уже безопасны,
// но в dataset браузер возвращает исходные символы.
var title = btn.dataset.title; // Название товара
var metaTitle = btn.dataset.metatitle; // Мета-тайтл (альтернативное название)
var url = btn.dataset.url; // URL товара
var langString = '{PHP.langSkStr.tools_copy_preff_title}'; // Языковая строка для атрибута title
// ------------------------------------------------------------
// Функция экранирования значений для HTML-атрибутов.
// Заменяет символы, способные сломать разметку атрибутов:
// & → & < → < > → > " → " ' → '
// Это обязательно для title и href, чтобы кавычки не «разрывали» атрибуты.
// ------------------------------------------------------------
function escapeAttr(str) {
if (!str) return '';
return str.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''');
}
// ------------------------------------------------------------
// Если название товара пустое, формируем заглушку из URL.
// ------------------------------------------------------------
var plainTitle = title;
if (!plainTitle || plainTitle.trim() === '') {
var slug = url.split('/').pop(); // последний сегмент URL
plainTitle = decodeURIComponent(slug.replace(/[-_]/g, ' '));
}
var plainMeta = metaTitle || plainTitle;
// ------------------------------------------------------------
// Сборка HTML-ссылки.
// В атрибутах title и href применяем escapeAttr(),
// а текст ссылки НЕ экранируем — чтобы он выглядел естественно
// (кавычки внутри текста допустимы).
// ------------------------------------------------------------
var html = '<a href="' + escapeAttr(url) + '" title="' + escapeAttr(langString + (metaTitle || '')) + '">' + title + '</a>';
var plain = '<a href="' + escapeAttr(url) + '" title="' + escapeAttr(langString + plainMeta) + '">' + plainTitle + '</a>';
// ------------------------------------------------------------
// Копирование в буфер обмена.
// Используем современный Clipboard API, а при его отсутствии —
// fallback с временным textarea.
// ------------------------------------------------------------
if (navigator.clipboard && navigator.clipboard.write) {
var clipboardItem = new ClipboardItem({
'text/html': new Blob([html], { type: 'text/html' }), // для визуальных редакторов
'text/plain': new Blob([plain], { type: 'text/plain' }) // для блокнота / исходного кода
});
navigator.clipboard.write([clipboardItem]).then(success).catch(function() { fallback(plain); });
} else {
fallback(plain); // резервный способ
}
// ------------------------------------------------------------
// Визуальная обратная связь: меняем текст и цвет кнопки на 2 секунды
// ------------------------------------------------------------
function success() {
btn.innerText = '{PHP.langSkStr.tools_copy_done}';
btn.classList.remove('btn-primary');
btn.classList.add('btn-success');
setTimeout(function() {
btn.innerText = '{PHP.langSkStr.tools_copy_link}';
btn.classList.remove('btn-success');
btn.classList.add('btn-primary');
}, 2000);
}
// ------------------------------------------------------------
// Резервный метод копирования (для старых браузеров)
// ------------------------------------------------------------
function fallback(text) {
var textarea = document.createElement('textarea');
textarea.value = text;
document.body.appendChild(textarea);
textarea.select();
try {
document.execCommand('copy');
success();
} catch (err) {
btn.innerText = 'Ошибка копирования';
}
document.body.removeChild(textarea);
}
}
</script>
результат:
<a href="https://cotonti/market/notebokers/somealias" title="Ноутбук Lenovo IdeaPad 1 15 Cloud Grey / 15.6"">Ноутбук Lenovo IdeaPad 1 15 Cloud Grey / 15.6"</a>
Пример работы скрипта для ноутбука с характеристиками, содержащими спецсимволы.
Модель: ASUS ZenBook 14 (Intel Core i7-1360P, 16GB RAM, 512GB SSD, 14″ 2.8K OLED).
1. HTML-версия (для визуальных редакторов, форумов и т.п.)
<a href="https://example.com/catalog/notebooks/asus-zenbook-14" title="Купить в Захалустье по низкой цене ASUS ZenBook 14 (Intel Core i7-1360P, 16GB RAM, 512GB SSD, 14" 2.8K OLED)">ASUS ZenBook 14 (Intel Core i7-1360P, 16GB RAM, 512GB SSD, 14" 2.8K OLED)</a>Что здесь происходит:
В атрибуте title символ дюйма " заменён на ", чтобы не «сломать» структуру HTML.
В тексте ссылки (между >...<) двойная кавычка осталась как есть — она отображается естественно (14" 2.8K OLED) и не нарушает разметку.
2. Plain-версия (для блокнота или исходного кода)
<a href="https://example.com/catalog/notebooks/asus-zenbook-14" title="Купить в Захалустье по низкой цене ASUS ZenBook 14 (Intel Core i7-1360P, 16GB RAM, 512GB SSD, 14" 2.8K OLED)">ASUS ZenBook 14 (Intel Core i7-1360P, 16GB RAM, 512GB SSD, 14" 2.8K OLED)</a>Как выглядит при вставке на форум/сайт:
Видимый текст ссылки:
ASUS ZenBook 14 (Intel Core i7-1360P, 16GB RAM, 512GB SSD, 14" 2.8K OLED)
Всплывающая подсказка (title):
Купить в Захалустье по низкой цене ASUS ZenBook 14 (Intel Core i7-1360P, 16GB RAM, 512GB SSD, 14" 2.8K OLED)
Таким образом, ссылка полностью рабочая, корректно отображается и не содержит «битого» HTML благодаря экранированию кавычек в атрибутах.
Итог:
Кнопка генерирует и копирует в буфер обмена готовую HTML-ссылку на товар с сохранением всех специальных символов в тексте, но с безопасным экранированием атрибутов — так, чтобы при вставке в любой редактор ссылка оставалась рабочей и корректно отображалась.