Раньше, чтобы скопировать текст в буфер обмена, приходилось использовать Флеш. Начиная с Сафари 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. Это был совет о веб‑разработке. Хотите знать всё о коде, тестах, фронтенд‑разработке, цеэсэсе, яваскрипте, рельсах и джейде? Присылайте вопросы.

Веб‑разработка
Отправить
Поделиться
Запинить

Рекомендуем другие советы