Как запретить браузеру выделять текст

6 января 2008 года   |  Разное

На просторах рунета всё больше и больше обсуждается вопрос: Как защитить свой уникальный контент от воровства?

Некоторые пытаются обращаться в суд, но при нашем законодательстве это полный бред.

Один из способов защиты информации от воровства это: Запрет копирования текста.

Интересная статья относительно данного способа:

Если Вы веб-разработчик, то у вас наверняка возникала необходимость в том, чтобы запретить пользователю выделение текста. Оговоримся, что я не имею ввиду полный запрет с целью защиты текста, а запрет на выделение всевозможных подписей, надписей и т.п. где выделение мешает работе интерфейса и пользователю (чаще всего при drag&drop, или выделении текста при двойном клике). Это в первую очередь касается веб-приложений и ни в коем случае не касается информационных сайтов.

Что же мы можем сделать? До сих пор думал немногое. Но прежде чем перейти к рассмотрению нового (лично для меня) методу, рассмотрим какие возможности борьбы с выделением текста предлагают нам браузеры.

Internet Explorer

Данный браузер дает нам две возможности:

  1. Для элементов устанавливаем атрибут unselectable со значением on. Но тут есть один нюанс: текст блока с таким атрибутом нельзя выделить (то есть нельзя начать выделение с данного элемента, и клик по такому элементу не будет снимать выделение с текста, если такой выделен), но если он содержит другие элементы (к примеру «безобидные» SPAN, B и т.д.) то текст в них выделить можно. К тому же если выделение текста начато с блока без такого атрибута, то текст внутри блока с атрибутом unselectable так же будет выделен. В такой ситуации решение одно — ставить всем (!) элементам данный атрибут, что неудобно и не практично.
  2. Перехват события selectstart. Другими словами добавив элементу onselectstart=»return false» (к примеру к BODY) запрещает выделение текста внутри него. Опять же нюанс: если начать выделять текст за пределами такого блока, то текст внутри него выделяется без проблем.

FireFox (браузеры на движке gecko), Safari (браузеры на движке KHTML)

Данные браузеры имеют более совершенный механизм, запрещающий выделение текста в любом виде. Делается это через CSS свойство user-select со значение none, которое включили в CSS3. Но до того как это свойство утверждено, браузеры демократично сделали это собственной фишкой движка назвав свойство -moz-user-select и -khtml-user-select соответственно. Получается, чтобы запретить выделять текст внутри блока, достаточно написать:

-moz-user-select: none;-khtml-user-select: none;

user-select: none;

И дело в шляпе.

Другие браузеры

А вот что касается других браузеров, то у них таких механизмов замечено не было. Вообще никаких. Конечно же Opera впереди планеты всей, для нее запрет выделения текста равносильно самому злостному преступлению. Но есть, есть один могильничек 🙂

Изучая вчера файл Оперы с хаками для сайтов, наткнулся на интересные строки:

document.addEventListener('mousemove',function(e)
{  if( e.target.getAttribute('unselectable')=='on' )

e.target.ownerDocument.defaultView.getSelection()
.removeAllRanges();,false);

Вспомним про атрибут unselectable у Internet Explorer’а, и становится ясным что в даном случае мы боремся с выделением текста. Развив идею, получилось некоторое кроссбраузерное решение:

function preventSelection(element){  var
preventSelection = false;
  function addHandler(element, event, handler){

if (element.attachEvent)

element.attachEvent('on' + event, handler);

else

if (element.addEventListener)

element.addEventListener(event, handler, false);

}

function removeSelection(){

if (window.getSelection) { window.getSelection
().removeAllRanges(); }

else if (document.selection &&
document.selection.clear)

document.selection.clear();

}

function killCtrlA(event){

var event = event || window.event;

var sender = event.target || event.srcElement;

if (sender.tagName.match(/INPUT|TEXTAREA/i))

return;

var key = event.keyCode || event.which;

if (event.ctrlKey && key == 'A'.charCodeAt(0))
  // 'A'.charCodeAt(0) можно заменить на 65

{

removeSelection();

if (event.preventDefault)

event.preventDefault();

else

event.returnValue = false;

}

}

// не даем выделять текст мышкой

addHandler(element, 'mousemove', function(){

if(preventSelection)

removeSelection();

});

addHandler(element, 'mousedown', function(event){

var event = event || window.event;

var sender = event.target || event.srcElement;

preventSelection = !sender.tagName.match
(/INPUT|TEXTAREA/i);

});

// борем dblclick

// если вешать функцию не на событие dblclick, можно
 избежать

// временное выделение текста в некоторых браузерах

addHandler(element, 'mouseup', function(){

if (preventSelection)

removeSelection();

preventSelection = false;

});

// борем ctrl+A

// скорей всего это и не надо, к тому же есть подозрение

// что в случае все же такой необходимости функцию нужно

// вешать один раз и на document, а не на элемент

addHandler(element, 'keydown', killCtrlA);

addHandler(element, 'keyup', killCtrlA);

}

Вызвав данную функцию, например:

preventSelection(document);

вы запретите выделение во всем документе, кроме элементов INPUT и TEXTAREA.

Комментарии:

  1. Opera не дает обрабатывать событие dblclick, так что в этом браузере все равно возможно выделить текст двойным кликом.
  2. Ctrl+A:
    1. В Opera длительное (2-3 секунды) удержание данной комбинации вызывает выделение текста до ее отпускания. Причем если первым отжать клавишу А а потом Ctrl, то выделение пропадает. Иначе остается.
    2. Safari не обрабатывает keydown для клавиш при зажатом Ctrl. Потому выделение текста пропадает только после отпускания клавиш. Причем для этого браузера характерно поведение Opera, в плане порядка отпускания клавиш (если первым отжать Ctrl, то выделение останется).
  3. Выделении текста двойным кликом:
    1. Safari & FireFox выделяют слово, и сразу снимают выделение. То есть присутствует эффект кратковременного выделения текста.
    2. Opera не дает запретить поведение по умолчанию. Она выделяет слово и вызывает контекстное меню.

Других особенностей не выявлено.

Тестировалось на FireFox 2.0.11, IE 6.0, Opera 9.24, Safari 3.0.3 (Win).

Конечно решение не идеальное, и требует JavaScript (с другой стороны это и нужно в веб-приложениях, которые и так используют JS). Но это лучше чем ничего, и довольно кроссбраузерно (конечно может потребоваться дополнительный код для некоторых браузеров и их версий).

Ввиду того, что многие к концу статьи видимо забывают начало, или не внимательно читают, повторяю первый суть первого абзаца. В данной статье я не решал задачу полного запрета выделения текста с целью его защиты от копирования, а имел ввиду запрет на выделение всевозможных подписей, надписей и т.п. там где выделение мешает работе интерфейса и пользователю (чаще всего при drag&drop, или выделении текста при двойном клике). Это в первую очередь касается веб-приложений и ни в коем случае не касается обычных информационных сайтов.

Иллюстрация к статье: Яндекс.Картинки

Читайте также

Статьи