Время для прочтения: 1 мин. 23 сек.

Запрет выделения текста на веб-странице

Бывают ситуации, когда пользователю необходимо запретить выделять текст на веб-странице или в каком-то определенном блоке, например при Drag&Drop. Попробуем найти кроссбраузерное решение.

Средствами HTML и CSS

Для запрета выделения текста есть свойство user-select, которое, естественно, пока не кроссбраузерно, но у каждого из браузеров уже есть реализация данного функционала. Берем кучу вендорных префиксов и получаем следующее:


*[unselectable=on] {
	-moz-user-select: none;
	-o-user-select:none;
	-khtml-user-select: none;
	-webkit-user-select: none;
	-ms-user-select: none;
	 user-select: none;
}

IE, как всегда, выделился, поэтому для него существует отдельный атрибут тега unselectable:


<div unselectable="on" onselectstart="return false;">текст</div>

Если в IE начать выделять текст за рамками этого элемента, то он очень хорошо выделяется

Средствами JavaScript (jQuery)

Суть скрипта — добавить все тот же набор CSS-правил для всех браузеров, создать атрибут unselectable и вернуть false при возникновении события onselectstart в IE.

Завернем наш скрипт в плагин, например jquery.disableSelection.js


jQuery.fn.extend({
    disableSelection : function() {
        this.each(function() {
            this.onselectstart = function() { return false; };
            this.unselectable = "on";
            jQuery(this).css({
                 '-moz-user-select': 'none'
                ,'-o-user-select': 'none'
                ,'-khtml-user-select': 'none'
                ,'-webkit-user-select': 'none'
                ,'-ms-user-select': 'none'
                ,'user-select': 'none'
            });
            // Для Opera
            jQuery(this).bind('mousedown', function() {
            	return false;
            });
        });
    }
});

На веб-странице вызываем его так:


<script type="text/javascript">
jQuery(function(){
    jQuery('body *').disableSelection(); 
});
</script>

Ссылки

Для вставки кода используйте HTML-теги
<pre><code class="php">ваш код</code></pre>

  • Спасибо за статью.
    Вы случайно не знаете, как грамотно сделать, чтобы выделение действовало на всё, кроме, допустим, инпутов.
    $j(‘body *’).not(«input»).disableSelection(); — не работает

    • Посмотрите filter()

    • Я обычно блокам, в которых надо запретить выделение текста, ставлю какой-нибудь класс и уже для этого класса применяю скрипт.

  • Oni

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

  • Егор

    Детские шалости. Обойти — 3 сек времени.

    • Понятно, что это «защита от дурака», но цель публикации показать возможный путь решения для большинства.

  • Я

    для оперы не работает

    • СМ. третью ссылку на хабре. Добавил в код заглушку под Opera (там есть коммент)

  • Larry

    Что же вы советуете людям, читающим блог? Очень неоптимизированная часть скрипта:

    [code]
    jQuery(this).css(‘-moz-user-select’, ‘none’);
    jQuery(this).css(‘-o-user-select’, ‘none’);
    jQuery(this).css(‘-khtml-user-select’, ‘none’);
    jQuery(this).css(‘-webkit-user-select’, ‘none’);
    jQuery(this).css(‘-ms-user-select’, ‘none’);
    jQuery(this).css(‘user-select’, ‘none’);
    [/code]

    заменить на

    [code]
    jQuery(this).css({
    ‘-moz-user-select’: ‘none’,
    ‘-o-user-select’: ‘none’,
    ‘-khtml-user-select’: ‘none’,
    ‘-webkit-user-select’: ‘none’,
    ‘-ms-user-select’: ‘none’,
    ‘user-select’: ‘none’
    });
    [/code]

    • Суть задачи — сделать рабочий прототип, оптимизация после. Это лишь пример. Не нужно в лоб копировать — своя же голова на плечах должна быть. А лично вам спасибо за оптимизацию — внес поправки в статью.