Пользователь
0,0
рейтинг
14 августа 2010 в 16:49

Разработка → jQuery плагин для добавления ссылок в буфер обмена

У многих из нас есть блоги, интернет-магазины, новостные сайты etc… Понятное дело стараемся опубликовывать оригинальный контент, но что же происходит после появления контента в интернетах, его конечно же просматривают и если он интересный, пользователи иногда обмениваются ссылкой на страничку с контентом. Новые переходы на нужную страницу и нам очень хорошо, а что если наш отличный текст просто взяли скопировали и скинули в аську\скайпик\почту — наш текст ушел, а перехода нету :(.

addtocopy plugin

Запретить копирование, это очень неправильно, весело и смешно ©, но мы ведь можем при копировании добавить в буфер обмена ссылку на наш сайтик. Рассмотрим как же нам это лучше сделать:



— Написать обработчик события для CTRL + C, «Копировать», придется работать с буфером обмена, а с ним не работается в современных браузерах.
— Использовать костыли в виде flash. Тоже не очень, +1 зависимость, да и в 10 версии для копирования в буфер нужен клик по интерфейсу флешки.
— А, что если будем смотреть что юзер выделяет курсором и аккуратно подсовывать нашу ссылку, хе хе хе, вот для реализации такого метода я и написал эту статью.

Работает все это как плагин для jQuery.

Создадим элемент на основе инициализации плагина, который будем подсовывать копипастеру.

var options = {htmlcopytxt: '<br>More: <a href="'+window.location.href+'">'+window.location.href+'</a>', minlen:25, addcopyfirst: false}
$.extend(options, usercopytxt);
var copy_sp = document.createElement('span');
copy_sp.id = 'ctrlcopy';
copy_sp.innerHTML = options.htmlcopytxt;



Если копипастер выделил текст, то добавляем нашу ссылку в выделенный текст.

$(this).mouseup(function(){
  if(window.getSelection){  //для хороших
    selected=window.getSelection();
    seltxt=selected.toString();
    nslct = selected.getRangeAt(0);
    seltxt = nslct.cloneRange();
    seltxt.collapse(false);
    seltxt.insertNode(copy_sp);
    nslct.setEndAfter(copy_sp);
    selected.removeAllRanges();
    selected.addRange(nslct);
  } else if(document.selection){  //для плохих
    selected = document.selection;
    nslct=selected.createRange();
    seltxt=nslct.text;
    seltxt=nslct.duplicate();
    seltxt.collapse(false);
    seltxt.pasteHTML(copy_sp.outerHTML);
    nslct.setEndPoint("EndToEnd",seltxt);
    nslct.select();
  }
});




При новом mousedown будем чистить старый копирайт-элемент со ссылкой.

$(this).mousedown(function(){
  $('#ctrlcopy').remove();
});



Естественно ссылка не должна быть видна, добавляем нужное оформление для нее:

<style>
  #ctrlcopy {
    height:1px;
    overflow:hidden;
    position:absolute;
    width:1px;
    margin: 5px 0 0 -1px;
    line-height:0;
    opacity: 0;
  }
</style>



Как пользоваться:

— Плагин: Скачать addtocopy

<script type="text/javascript">
  $(function(){
    $("#content").addtocopy({htmlcopytxt: '<br>Подробнее: <a href="'+window.location.href+'">'+window.location.href+'</a>', minlen:35, addcopyfirst: false});
  });
</script>



Опции обрабатываемые плагином:

Опция Описание
htmlcopytxt что добавлять к скопированному в буфер, принимает html
minlen минимальная длинна выделяемого текста, принимает int
addcopyfirst добавлять htmlcopytxt в начало буфера обмена или в конец, true/false


Пример: тут

Известные глюки:
В Опере текст выделяется с лева на право
В Firefox'e если addcopyfirst: true, то текст в первый раз не выделяется
be3 @be3_max
карма
32,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Спецпроект

Самое читаемое Разработка

Комментарии (49)

  • +2
    Chrome 6.0.490.1 dev — пример не работает.
    • –1
      Chromium 5.0.375.125 (53311) Ubuntu 10.10 — пример работает o_O
    • +1
      Спасибо, поправил.
  • +3
    Работает только при выделении слева направо. В обратном порядке — нет.

    Opera 10.70 (6428) x86_64, 2.6.34-zen1
  • 0
    В Chrome Dev 6.0.490.1 всё работает во всех направлениях, видимо автор уже поправил.
  • +2
    Где то год назад копировал статью на одном сайтике, там там контекстная реклама от гугля добавлялась в центр статейки. Заметил не сразу )) Копипаст он такой коварный :))
  • 0
    Сделайте проверку, что если выделен пустой текст, то ссылку не добавлять. Это логичнее будет.
  • +3
    Попробовал — не работает, думал писать зловредный камент А потом вспомнил, что не отключил Noscript на странице. FireFox 3.6 работает. В ИЕ8 глюк — при двойном клике по слову не выделяется ничего. Вообще, подумайте о том, что из-за пары слов не стоит добавлять к ним линк. Хочу выделить слово-два поискать, а оно линк туда сует.
    • +2
      Спасибо :), добавил параметр minlen, в который можно передавать минимально выделяемый текст, плагин и пример обновил.
  • 0
    1. Если выделить так, что выделение заканчивается точкой в конце абзаца, то подсвечивается выделенным вся страница ниже этой точки, по всей ширине.
    2. Ctrl+A Ctrl+C — ссылка не вставляется.

    Chromium 5.0.375.99
  • +2
    Отличный скрипт. Дорабатывайте!

    P.S. Опубликуйте в каком-нибудь блоге, а то на главной не показывается.
    Я специально залогинился, чтоб плюсануть пост :)
  • –1
    У меня автоматически копируется выделенный текст — скрипт не срабатывает.
    FF 4.0b3
  • 0
    Мак ОС, Хром 6.0.490.1 dev не пашет, сбрасывает выделение. А так — прикольно.
    • 0
      а, не работает копирование из контекстного меню, а с клавы пашет
  • +1
    Может, добавить возможность установки ссылки перед скопированным текстом?
    • 0
      Да, добавил параметр addcopyfirst: true/false, может кому то пригодится, плагин обновил.
  • 0
    У меня при выделении всего текста ссылка не добавляется
    Opera 10.70 (3483)
  • +1
    мне подумалась немного другая идея плагина… хотя на плагин она в принципе и не тянет. суть в том, что смысла выделить просто текст и добавить к нему ссылку я не особо вижу. да и не каждый просит ему прислать ссылку с цитатой. а вот сделать срипт, который мог бы копировать сразу и заголовок статьи и ссылку на нее и вставлять в буфер — это было бы полезно. аналог кнопки для твиттера и тд, но только сохранять в буфер.
  • +7
    не вмешивайтесь в мой буфер обмена!
    • +2
      Поддерживаю. В FF есть возможность выделять несколько кусочков текста одновременно. Делается это Ctrl. С данным плагином уже не делается.
      • 0
        О, спасибо — интересная фича!
    • 0
      Поддерживаю! Вы делаете сайт, вот сайтом и занимайтесь. В мой браузер лезть НЕЛЬЗЯ! За девяностые и начало двутысячных жуть как задолбали сайты блокирующие копи-пасту, сохранение картинок и т.д. Если не хотите делиться контентом — не выкладывайте его в публичный доступ.
  • 0
    Выделяешь первые 3 слова — не работает.
    • 0
      и по буковке выделяешь, тоже не работает
      • +1
        я думал это фича
  • +2
    У меня была другая идея. Если выделять часть текста, то способ не работает, но можно подумать как улучшить. В общем, можно добавлять, скажем, в конец текста однопиксельную прозрачную gif-картинку с альтом в виде ссылки на источник. При копировании текста, браузер помещает в буффер обмена alt картинки, вместо самой картинки. Таким образом мы получим желаемый результат. Плюс способа в том, что он будет работать с выключенным javascript и можно перенести процесс добавления картинки на плечи серверного скрипта.
    • +1
      Да можно и текстом, а не картинкой в скрытом span или div — автор так и делает, просто добавляет его динамически.
      Я где-то такое уже встречал, в середине статьи между абзацами были «закладки» с адресом статьи и именем автора.
  • +1
    И еще если начать выделять и не отпуская клавишу мышки нажать Ctrl+C то ссылка тоже не вставляется)
  • 0
    У вас такой вкусный код получился, завидую белой завистью. С ужасом вспоминаю какие-то свои куски, к финальной версии превращающиеся коктейль из костылей, хаков и «страховочных» экспрешенов…
    • 0
      На то фреймворки и делают, чтоб костыли не писать, а только вызывать :-D
  • 0
    Если выделять текст двойным/тройным кликом в опере, то ссылка не вставляется.
  • –1
    Не работает в Safari.
  • 0
    интересно, а такая технология позволяет воровать пользовательский буффер?
    • 0
      Прочтите статью внимательнее. Работа непосредственно с буфером не происходит.
      • –1
        Я просто подумал, что flash умеет читать из буффера. Сейчас посмотрел — все в порядочке. спим спокойно :)
  • –1
    Идея отличная, но на всеобщее обозрение выкладывать вы поторопились — не работает нифига…
  • 0
    буфер обмана какой-то получается
  • –1
    у меня в хроме(5.0.375.126) выделенный текст двоиться

    в фф, нормально
  • –2
    Ваш код не проходит валидацию jslint и написан без единого var.
  • 0
    По Ctrl+X тоже не работает.
    Хромиум 5.0.375.125, Arch.
  • 0
    safari 5.0.1 работает справа налево и слева направо.
    Только почему-то если выделить абзац целиком, то появляется выделение всей страницы, но копируется только абзац.
  • 0
    Глюк в Опера 10.61: в буфер попадает весь текст от начала выделения до конца страницы.
  • +1
    Огромное человеческое спасибо!
    Как раз к своему последнему проекту применю…
  • +1
    Кажется, этим пользуется РБК и Коммерсантъ.
    • 0
      wow, приятно.
  • 0
    При событии mouseup мышка не всегда находится над нужным элементом. Поэтому я вешаю плагин не на ссылку или ее родителя, а на html
  • +1
    Нда… плагин работает кривовато немного. Привожу код из www.adme.ru
    Работает отлично, нету проблем при полном выделении (Ctrl+A)
    (function($) {
        $(function() {
            function addLink() {
                   var body_element = document.getElementsByTagName ('body') [0];
                   var html = "";
                   if (typeof window.getSelection != "undefined") {
                       var selection = window.getSelection();
                       if (selection.rangeCount) {
                           var container = document.createElement("div");
                           for (var i = 0, len = selection.rangeCount; i < len; ++i) {
                               container.appendChild(selection.getRangeAt(i).cloneContents());
                           }
                           html = container.innerHTML;
                       }
                   } else {
                       return;
                   }
                   if (html.toString().split(' ').length < 10) {
                       return;
                   }
    
                   var pagelink = "<br/><br/> Источник: <a href='" + document.location.href+ "'>"  +document.location.href+ "</a> © AdMe.ru";
                   var copytext = html + ' ' + pagelink;
                   var newdiv = document.createElement('div');
                   newdiv.style.position = 'absolute';
                   newdiv.style.left = '-99999px';
                   body_element.appendChild(newdiv);
                   newdiv.innerHTML = copytext;
                   selection.selectAllChildren(newdiv);
                   window.setTimeout(function() {
                       body_element.removeChild(newdiv);
                   },0);
            }
            document.oncopy = addLink;
        });
    })(jQuery);
    
    • 0
      Жалко толъко, что в IE не пашет )
  • 0
    автор, как там дела? какие доработки?

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.