x
 
Егор Георгиевич
22 ноября 2018
Советы почтой каждую неделю
Пожалуйста, получите наше письмо, чтобы подтвердить свой адрес:
Вы подписаны на «Советы за неделю»:

Как работает кнопка «Скопировать» в подборках? Откуда в буфере обмена берётся текст, которого нет в тексте подборки?


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

Поделиться
Отправить

Цель рубрики — обсуждение вопросов дизайна всех видов, текста в дизайне и взаимоотношений дизайнеров с клиентами.

Мы публикуем комментарии, которые добавляют к уже сказанному новые мысли и хорошие примеры. Мы ожидаем, что такие комментарии составят около 20% от общего числа.

Решение о публикации принимается один раз; мы не имеем возможности комментировать или пересматривать свое решение, хотя оно может быть ошибочно. Уже опубликованные комментарии могут быть удалены через некоторое время, если без них обсуждение не становится менее ценным или интересным.

Вот такой веб 2.0.

Каким способом сделать простую анимацию на спрайтах Как устроена беспарольная аутентификация почтой 7




Недавно всплыло

Практика: формулировка полезного действия 8 Как избежать «эффекта Тильды»? 2 2 1