203

Does jQuery or jQuery-UI have any functionality to disable text selection for given document elements?

Peladao
  • 4,036
  • 1
  • 23
  • 43
Dawid Ohia
  • 16,129
  • 24
  • 81
  • 95

13 Answers13

275

In jQuery 1.8, this can be done as follows:

(function($){
    $.fn.disableSelection = function() {
        return this
                 .attr('unselectable', 'on')
                 .css('user-select', 'none')
                 .on('selectstart', false);
    };
})(jQuery);
pimvdb
  • 151,816
  • 78
  • 307
  • 352
SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • 1
    The JavaScript alternative works only for IE. "onselectstart" is not available for other browsers – Omar Abid Apr 23 '10 at 16:32
  • 13
    @Omar: I'm well aware of that. – SLaks Apr 23 '10 at 16:33
  • Unfortunately they can still do a select all (through menu or key combpo) and get a selection (in Chrome, Safari, and Firefox AFAIK). Do you know of a solution to this? I am sure I can grab the keypress and return false in case of CTRL-C or CTRL-A but that does not help if they use the browser menu to select text. So far my only thoughts on a solution to this is to embed the text inside a Flash object. – Bryce Cutt Feb 08 '11 at 07:04
  • 2
    @Bryce: Just don't. http://blog.slaks.net/2010/12/on-copy-prevention-in-html-part-2.html http://blog.slaks.net/2010/12/on-copy-prevention-in-html-part-3.html – SLaks Feb 08 '11 at 12:55
  • @SLaks: Nice! Thanks for that jolt of inspiration. Based on the inflate method I can easily write up a solution that will foil non-programmers. Your other solutions are overkill for my problem. – Bryce Cutt Feb 22 '11 at 11:18
  • 12
    Thanks for this. I was working on a dragging slider and needed a way that text wouldn't be selected in the process. – Spencer Ruport Nov 14 '11 at 06:11
  • Thank you. I'm surprised this isn't done for [jQuery UI buttons](http://jqueryui.com/demos/button/radio.html). I accidentally selected text instead of clicking the button several times. – styfle Feb 12 '12 at 04:38
  • jQuery UI buttons not implementing this, specifically on buttonsets, is disappointing. – nokturnal May 28 '12 at 19:58
  • @SLaks how would your then re-enable? – Skylar Saveland Apr 20 '13 at 22:36
  • @SkylarSaveland: Reverse each of those settings. – SLaks Apr 21 '13 at 01:30
  • @SLaks: This answer should include `.css('MozUserSelect','none')` to cover Firefox. – Mottie Apr 30 '13 at 14:16
  • 1
    @Mottie: Wrong; jQuery does that automatically. See the edit history. – SLaks Apr 30 '13 at 19:41
  • @SLaks: correct, I should have said, jQuery older than v1.8 needs the `.css('MozUserSelect', 'none')` for it to work in Firefox. – Mottie May 01 '13 at 02:56
  • 37
    To those of you who say "just don't" to disabling text selection (or anything else on SO for that matter), open thy minds just a bit. Often times people disable it for aesthetic reasons such as avoiding text selection on a double click of a label with text in it, etc. So either answer the question, or provide an actual counter point and specify what you're talking about negating, don't just scratch the idea out in a general manner. – dudewad Nov 03 '13 at 20:21
  • @SLaks's answer is exactly how jQuery UI Core lib provided the API `disableSelection` http://api.jqueryui.com/disableSelection/ However, it's a short lived feature. jQuery UI core removed it since v1.9 (was added at v1.6). – Devy May 15 '14 at 19:38
  • Sorry for asking, but how can I select my specific element? I want to select this: `#idname` – stack Jan 21 '16 at 07:44
  • 1
    @stack This creates a new "disableSelection" method that you can use. So you can call it like: $("#idname").disableSelection(); – salonMonsters Sep 20 '16 at 19:43
  • I am using the disable body selection prior to dynamically adding and displaying a modal window. What code would be used restore selectability after the window is closed? – Richard Feb 23 '17 at 11:32
  • @Richard: Just remove / unbind each of these. – SLaks Feb 23 '17 at 22:50
101

If you use jQuery UI, there is a method for that, but it can only handle mouse selection (i.e. CTRL+A is still working):

$('.your-element').disableSelection(); // deprecated in jQuery UI 1.9

The code is realy simple, if you don't want to use jQuery UI :

$(el).attr('unselectable','on')
     .css({'-moz-user-select':'-moz-none',
           '-moz-user-select':'none',
           '-o-user-select':'none',
           '-khtml-user-select':'none', /* you could also put this in a class */
           '-webkit-user-select':'none',/* and add the CSS class here instead */
           '-ms-user-select':'none',
           'user-select':'none'
     }).bind('selectstart', function(){ return false; });
Maxime Lorant
  • 34,607
  • 19
  • 87
  • 97
Damien
  • 5,872
  • 2
  • 29
  • 35
  • 1
    the jquery ui function would be great, but it doesn't offer the same level of protection, it does prevent selecting things directly, but if you're carrying a selection from another dom object, you need the css rules too - heres the function = function () { return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) + ".ui-disableSelection", function( event ) { event.preventDefault(); }); } – chrismarx Aug 04 '11 at 19:21
  • 2
    Note that disableSelection() is deprecated in jQuery UI 1.9 – mar10 May 14 '13 at 06:09
  • It could also require .on('mousedown', false) to work, depending on your browser. Hovewer, it's dangerous to kill mousedown events on by default because this could probably brake existing functionality – Dan Jul 18 '13 at 11:59
  • 1
    Arg. It's annoying it's been depreciated. There's plenty of time when you want this legitimately. – Chuck Le Butt Aug 06 '13 at 16:19
  • I'm creating a right-click context menu on some anchor text, and I don't want the text to select on click. So yes, @Monk, this would qualify as a legitimate example. – Wayne Smallman Jun 25 '14 at 21:03
  • do we still need to include vendor prefixes in jquery `.css()`? – Ari Jul 04 '15 at 15:16
76

I found this answer ( Prevent Highlight of Text Table ) most helpful, and perhaps it can be combined with another way of providing IE compatibility.

#yourTable
{
  -moz-user-select: none;
  -khtml-user-select: none;
  -webkit-user-select: none;
  user-select: none;
}
Community
  • 1
  • 1
Plynx
  • 11,341
  • 3
  • 32
  • 33
  • Chrome uses -webkit-user-select – tim Sep 06 '12 at 20:55
  • 3
    Always appreciate the CSS way to do things instead of using jQuery or JS in general. Just like jQuery animations vs CSS transitions, the way built into the browser is always going to be the best and most efficient. – Brian Leishman Mar 27 '15 at 18:29
17

Here's a more comprehensive solution to the disconnect selection, and the cancellation of some of the hot keys (such as Ctrl+a and Ctrl+c. Test: Cmd+a and Cmd+c)

(function($){

  $.fn.ctrlCmd = function(key) {

    var allowDefault = true;

    if (!$.isArray(key)) {
       key = [key];
    }

    return this.keydown(function(e) {
        for (var i = 0, l = key.length; i < l; i++) {
            if(e.keyCode === key[i].toUpperCase().charCodeAt(0) && e.metaKey) {
                allowDefault = false;
            }
        };
        return allowDefault;
    });
};


$.fn.disableSelection = function() {

    this.ctrlCmd(['a', 'c']);

    return this.attr('unselectable', 'on')
               .css({'-moz-user-select':'-moz-none',
                     '-moz-user-select':'none',
                     '-o-user-select':'none',
                     '-khtml-user-select':'none',
                     '-webkit-user-select':'none',
                     '-ms-user-select':'none',
                     'user-select':'none'})
               .bind('selectstart', false);
};

})(jQuery);

and call example:

$(':not(input,select,textarea)').disableSelection();

jsfiddle.net/JBxnQ/

This could be also not enough for old versions of FireFox (I can't tell which). If all this does not work, add the following:

.on('mousedown', false)
Community
  • 1
  • 1
Vladimir
  • 179
  • 1
  • 2
  • 3
    Why do you call `attr('unselectable', 'on')` twice? Is it a typo or is it useful? – KajMagnus Feb 02 '12 at 07:30
  • This worked great for me, but I had to disable the ".each(function() { $(this).attr('unselectable','on') .bind('selectstart',function(){ return false; }); });" section for my particular web app (JQuery Mobile), just in case it helps anyone.. – Anthony Apr 25 '13 at 19:54
14

The following would disable the selection of all classes 'item' in all common browsers (IE, Chrome, Mozilla, Opera and Safari):

$(".item")
        .attr('unselectable', 'on')
        .css({
            'user-select': 'none',
            'MozUserSelect': 'none'
        })
        .on('selectstart', false)
        .on('mousedown', false);
Zach Barham
  • 457
  • 1
  • 8
  • 18
Arvid Vermote
  • 433
  • 5
  • 6
  • 1
    Not complicated - Excellent! Thank you. For disabled looking; I addded .attr('disabled', 'disabled') – freewill Sep 10 '14 at 15:05
  • Update: instead of .attr('disabled', 'disabled'), I used .attr('readonly', 'readonly'). Disabled prevents posting my model variable in MVC(model variable is null). Readonly still have disabled looking(I use bootstrap) and it allows posting the item value – freewill Sep 11 '14 at 13:59
  • Excellent bro, i using this code to replace "pointer-events: none;", that not work in IE 11. regards – Shortys Oberto Dutari Oct 09 '18 at 12:56
7
        $(document).ready(function(){
            $("body").css("-webkit-user-select","none");
            $("body").css("-moz-user-select","none");
            $("body").css("-ms-user-select","none");
            $("body").css("-o-user-select","none");
            $("body").css("user-select","none");
        });
deerhunter
  • 87
  • 1
  • 1
6

This is actually very simple. To disable text selection (and also click+drag-ing text (e.g a link in Chrome)), just use the following jQuery code:

$('body, html').mousedown(function(event) {
    event.preventDefault();
});

All this does is prevent the default from happening when you click with your mouse (mousedown()) in the body and html tags. You can very easily change the element just by changing the text in-between the two quotes (e.g change $('body, html') to $('#myUnselectableDiv') to make the myUnselectableDiv div to be, well, unselectable.

A quick snippet to show/prove this to you:

$('#no-select').mousedown(function(event) {
  event.preventDefault();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span id="no-select">I bet you can't select this text, or drag <a href="#">this link</a>, </span>
<br/><span>but that you can select this text, and drag <a href="#">this link</a>!</span>

Please note that this effect is not perfect, and performs the best while making the whole window not selectable. You might also want to add

the cancellation of some of the hot keys (such as Ctrl+a and Ctrl+c. Test: Cmd+a and Cmd+c)

as well, by using that section of Vladimir's answer above. (get to his post here)

Community
  • 1
  • 1
Zach Barham
  • 457
  • 1
  • 8
  • 18
6

This can easily be done using JavaScript This is applicable to all Browsers

<script type="text/javascript">

/***********************************************
* Disable Text Selection script- © Dynamic Drive DHTML code library (www.dynamicdrive.com)
* This notice MUST stay intact for legal use
* Visit Dynamic Drive at http://www.dynamicdrive.com/ for full source code
***********************************************/

function disableSelection(target){
if (typeof target.onselectstart!="undefined") //For IE 
    target.onselectstart=function(){return false}
else if (typeof target.style.MozUserSelect!="undefined") //For Firefox
    target.style.MozUserSelect="none"
else //All other route (For Opera)
    target.onmousedown=function(){return false}
target.style.cursor = "default"
}
 </script>

Call to this function

<script type="text/javascript">
   disableSelection(document.body)
</script>
miket
  • 3
  • 1
Code Spy
  • 9,626
  • 4
  • 66
  • 46
4

I've tried all the approaches, and this one is the simplest for me because I'm using IWebBrowser2 and don't have 10 browsers to contend with:

document.onselectstart = new Function('return false;');

Works perfectly for me!

Dave
  • 1,521
  • 17
  • 31
1

1 line solution for CHROME:

body.style.webkitUserSelect = "none";

and FF:

body.style.MozUserSelect = "none";

IE requires setting the "unselectable" attribute (details on bottom).

I tested this in Chrome and it works. This property is inherited so setting it on the body element will disable selection in your entire document.

Details here: http://help.dottoro.com/ljrlukea.php

If you're using Closure, just call this function:

goog.style.setUnselectable(myElement, true);

It handles all browsers transparently.

The non-IE browsers are handled like this:

goog.style.unselectableStyle_ =
    goog.userAgent.GECKO ? 'MozUserSelect' :
    goog.userAgent.WEBKIT ? 'WebkitUserSelect' :
    null;

Defined here: http://closure-library.googlecode.com/svn/!svn/bc/4/trunk/closure/goog/docs/closure_goog_style_style.js.source.html

The IE portion is handled like this:

if (goog.userAgent.IE || goog.userAgent.OPERA) {
// Toggle the 'unselectable' attribute on the element and its descendants.
var value = unselectable ? 'on' : '';
el.setAttribute('unselectable', value);
if (descendants) {
  for (var i = 0, descendant; descendant = descendants[i]; i++) {
    descendant.setAttribute('unselectable', value);
  }
}
1

I think this code works on all browsers and requires the least overhead. It's really a hybrid of all the above answers. Let me know if you find a bug!

Add CSS:

.no_select { user-select: none; -o-user-select: none; -moz-user-select: none; -khtml-user-select: none; -webkit-user-select: none; -ms-user-select:none;}

Add jQuery:

(function($){
    $.fn.disableSelection = function() 
    {       
        $(this).addClass('no_select');              
        if($.browser.msie)
        {
            $(this).attr('unselectable', 'on').on('selectstart', false);            
        }
    return this;            
};
})(jQuery);

Optional: To disable selection for all children elements as well, you can change the IE block to:

$(this).each(function() {
    $(this).attr('unselectable','on')
    .bind('selectstart',function(){ return false; });
});

Usage:

$('.someclasshere').disableSelection();
Justin
  • 26,443
  • 16
  • 111
  • 128
0

One solution to this, for appropriate cases, is to use a <button> for the text that you don't want to be selectable. If you are binding to the click event on some text block, and don't want that text to be selectable, changing it to be a button will improve the semantics and also prevent the text being selected.

<button>Text Here</button>
-1

Best and simplest way I found it, prevents ctrl + c, right click. In this case I blocked everything, so I don't have to specify anything.

$(document).bind("contextmenu cut copy",function(e){
    e.preventDefault();
    //alert('Copying is not allowed');
});
Marcelo Rocha
  • 820
  • 8
  • 7