Раньше, чтобы скопировать текст в буфер обмена, приходилось использовать Флеш. Начиная с Сафари 10, в буфер обмена можно копировать на голом Яваскрипте:
// какой элемент будем копировать в буфер обмена
const $el = document.querySelector('.js__copy')
// выделяем его
const range = document.createRange()
range.selectNode($el)
// подчищаем предыдущее выделение
window.getSelection().removeAllRanges()
// добавляем своё
window.getSelection().addRange(range)
// копируем в буфер обмена
document.execCommand('copy')
// подчищаем выделение скопированного элемента
window.getSelection().removeAllRanges()
Чтобы изменить или дополнить скопированный текст, в обработчике события copy
можно поменять данные в буфере обмена:
$el.addEventListener('copy', (e) => {
// клонируем выделенный фрагмент
const selection = window.getSelection()
const range = selection.getRangeAt(0)
const clonedSelection = range.cloneContents()
// конвертируем фрагмент в плейн текст и записываем КАПСОМ
const plainText = clonedSelection.textContent.toUpperCase()
// подменяем текст в буфере обмена на преобразованный
e.clipboardData.setData('text/plain', plainText)
e.preventDefault()
})
Когда пользователь копирует текст подборки, мы похожим образом «достраиваем» его: добавляем название, описание, автора, картинку, форматируем текст и заменяем ссылки на полные урлы.
В коде это выглядит примерно так:
const onCopy = (e) => {
// Создаём «клона» — копию ДОМа текста подборки.
// В него мы будем добирать недостающую информацию
const selection = window.getSelection()
const range = selection.getRangeAt(0)
const html = range.cloneContents()
const $clone = $('<div>').append(html)
// Заменяем ссылки на полные урлы
$clone.find('a').each((_, el) => el.textContent = el.href)
// Форматируем текстовые элементы: списки, абзацы и заголовки
$clone.find('br').replaceWith('\n')
$clone.find('li:not(:first-child)').before('\n')
$clone.find('p').before('\n')
$clone.find('h1, h2, h3').before('\n\n')
// Собираем дополнительную информацию о подборке из других
// элементов на странице
const coverLink = $('meta[property="og:image"]').attr('content')
const title = $('.js__compilationTitle').text().trim()
const summary = $('.js__compilationSummary').text().trim()
const author = $('.js__compilationAuthor').text().trim()
const meta = [title, summary, author]
.filter(part => part)
.join('\n')
// Добавляем всю собранную информацию в клон
$clone.prepend($(`<p>${meta}\n\n</p>`))
$clone.prepend($(`<p>${coverLink}\n\n\n</p>`))
// Меняем текст в буфере обмена на текст, получившийся в клоне
e.clipboardData.setData('text/plain', $clone[0].textContent)
e.preventDefault()
}
P. S. Если вам нужно просто скопировать часть страницы по клику на кнопку, лучше возьмите готовое решение — Clipboard.js.
P. P. S. Это был совет о веб‑разработке. Хотите знать всё о коде, тестах, фронтенд‑разработке, цеэсэсе, яваскрипте, рельсах и джейде? Присылайте вопросы.