Disable Text Selection With jQuery

Saturday, February 07, 2009

I was recently working on an interface where there would be a log of dragging, scrolling and clicking - an unfortunate side effect of these type of things is that the user may sometimes unintentionally select text. Which this doesn't break anything, it just looks bad can ruin the smooth experience you are trying to present the user with. It turns out that every browser has either some kind of hidden CSS or javascript function to prevent text selection.

I searched around and eventually came across this page on James Dempster's site. He wrote a simple jQuery plugin to turn off text selection only for the elements you specify. His plugin works just fine, but I believe it can be simplified. Below is my version.

$(function(){
	$.extend($.fn.disableTextSelect = function() {
		return this.each(function(){
			if($.browser.mozilla){//Firefox
				$(this).css('MozUserSelect','none');
			}else if($.browser.msie){//IE
				$(this).bind('selectstart',function(){return false;});
			}else{//Opera, etc.
				$(this).mousedown(function(){return false;});
			}
		});
	});
	$('.noSelect').disableTextSelect();//No text selection on elements with a class of 'noSelect'
});

After you include jQuery on your page, just include this script and any element with a class of noSelect will not be able to have it's text highlighted — easy! (Obviously you can change the class name to be whatever you want though.)

Do take note that the plugin is contained within the $(document).ready(function(){/*your code here*/}); (which can also be written as $(function(){/*your code here*/}).) That just sets it up as a method to be called. To call the method and disable text selection you just get a standard jQuery element and add the method onto it : $('.noSelect').disableTextSelect();

Posted by Chris Barr on 02/07 at 07:30 PM
Filed under Web, Code, Javascript
Comments
1
Ville Walveranta commented on Feb 28, 2009 at 09:45 pm

This was useful. Thanks for sharing!

2
.(JavaScript must be enabled to view this email address) commented on Jun 26, 2009 at 12:53 am

Great idea and lightweight !
Thanks a lot for sharing !

3
Jeff commented on Aug 7, 2009 at 05:38 pm

Excellent solution - thanks a bunch for sharing.  Works perfectly!

4
Ray Brown commented on Aug 27, 2009 at 09:43 pm

I’m building an on-screen keyboard for a client’s kiosk center, and this script really helps polish the UX by avoiding awkward text selection.  Thanks a bunch!

5
.(JavaScript must be enabled to view this email address) commented on Sep 30, 2009 at 07:01 pm

Thanks for sharing! exactly what i needed.

6
bara commented on Oct 21, 2009 at 07:58 am

just a note by using “live” instead of “bind” u dont have to rebind if u add elements after the code is executed

7
.(JavaScript must be enabled to view this email address) commented on Dec 10, 2009 at 05:09 pm

For portable code, you should use ‘jQuery’ instead of ‘$’ in case jQuery.noConflict is on.

8
.(JavaScript must be enabled to view this email address) commented on Jan 15, 2010 at 07:29 pm

Hi friend,

It isn’t working in Opera 10 , any solution please?

9
Tim commented on Apr 5, 2010 at 12:55 pm

In the jQuery-ui core.js, it uses something similar, which I’ve found to be a slightly more reliable snippet of reusable code, in light of the Opera 10 comment just above.  I try to avoid jQuery-ui as a full-blown library just for simple things like this, so having the snippet built into my own code is quite nice.

jQuery(this)
  .attr(‘unselectable’, ‘on’)
  .css(‘MozUserSelect’, ‘none’)
  .bind(‘selectstart.ui’, function() {
  return false;
  });

10
.(JavaScript must be enabled to view this email address) commented on May 4, 2010 at 03:07 am

Hey, this works great! Even better if you add the 9th post fix. But I have a question… I’m adding a lot of dynamic content to the page that must have noSelect class in order to not be selected, so each time the content changes, I must call the function to refresh the “selection prevention” and when I am having to much elements on the page, it stalls a little… But, if I enclose all of my content in a DIV and let it be noSelect, it is really fast, but <input> and <select> tags in that DIV become unusable… Can I somehow make certain elements inside noSelect DIV selectable? I tried to reverse your method, it works if I disable/enable the main DIV, but it doesn’t work on its child elements…

11
Chris Barr commented on May 4, 2010 at 10:03 pm

Well, selecting by a class name instead of an ID is always slower, so if it’s always one element or the same elements with predicable ID’s just use that instead.

That should make it a bit faster, but I’m not sure there’s an easy way to make it not disable form elements.  All I can think of is that you could possibly select your element you want to disable, and disable everything inside it except for those elements instead of the element itself.

$(”#MyElement”).children(”:not(input,select)”). disableTextSelect();

That might work, but that also might slow things down again if the element has a lot of children.

12
Dakkar Daemor commented on May 10, 2010 at 02:14 am

I’ve made some very minor changes to improve it :-)

/**
http://chris-barr.com/entry/disable_text_selection_with_jquery/
*  modified to be “$” safe by Dakkar Daemor [www.imaginific.com]
*/
(function($) {
  $.fn.disableTextSelect = function() {
      return this.each(function(){
        if($.browser.mozilla){//Firefox
          $(this).css(‘MozUserSelect’,‘none’);
        }else if($.browser.msie){//IE
          $(this).bind(‘selectstart’,function(){return false;});
        }else{//Opera, etc.
          $(this).mousedown(function(){return false;});
        }
      });
  }
  $(function($){
      $(’.noSelect’).disableTextSelect();//No text selection on elements with a class of ‘noSelect’
  });
})(jQuery);

13
rycka commented on Jun 5, 2010 at 06:22 am

Useful. Thanks.

14
Stuart commented on Jun 9, 2010 at 04:01 am

Very useful, thanks.  Most of our users would like the same dbl click functionality as found in Windows, and quite often when the text is highlighted in a table row, it looks messy and dated.

15
.(JavaScript must be enabled to view this email address) commented on Jun 10, 2010 at 06:19 am

P E R F E C T - thanx!!!! =))))

16
.(JavaScript must be enabled to view this email address) commented on Jul 2, 2010 at 02:27 pm

Awesome plugin.  Thanks!

17
.(JavaScript must be enabled to view this email address) commented on Aug 24, 2010 at 10:27 pm

many thanks

18
Seemly commented on Sep 1, 2010 at 03:41 am

Many thanks for this plugin, it helped with a current project of mine.

Kudos!

19
.(JavaScript must be enabled to view this email address) commented on Sep 1, 2010 at 08:43 am

Excellent plugin. Saved me loads of time…. Thanks for sharing!

20
Asmor commented on Sep 10, 2010 at 12:58 pm

Many thanks! Was working on a yes/no/maybe form element and was getting ugly selections if one clicked twice quickly (i.e. double clicked). This solved it nicely!

21
.(JavaScript must be enabled to view this email address) commented on Nov 9, 2010 at 03:12 am

Thanks a lot, this script works well.

But how would you disable text selection in Chrome?

I’ve already found out that $.browser.safari returns true when in Chrome but I don’t know how to disable text selection…

22
.(JavaScript must be enabled to view this email address) commented on Nov 9, 2010 at 05:27 am

regarding my previous comment
BTW: using webKitUserSelect does not work.

webKitUserSelect might work for fixed text but I’m using this script to disable text selection in a textbox. When using webKitUserSelect I cannot enter text at all

23
Chris Barr commented on Nov 9, 2010 at 08:25 am

@Stif - what you should use instead id $.browser.webkit because $.browser.safari will be depreciated soon in jQuery.  Both Chrome and Safari use the same Webkit engine for rendering HTML.

The code here should just work in Safari and Chrome.

24
Shiro commented on Nov 19, 2010 at 02:45 pm

This code is not working
$(”#MyElement”).children(”:not(input,select)”). disableTextSelect();

I used all the possible combination to make a child element selectable, but it never work for me.

Have you test it if it working?

For example, I disable selection on the <body> tag, and enable selection on the tag.

It never work for me.

Please help, thanks

25
Chris Barr commented on Nov 19, 2010 at 02:49 pm

@Shiro
No, it doesn’t work that way.  If you disable it on a parent element, then nothing inside it would be selectable.  You will have to only select the elements you want to disable.

26
Shiro commented on Nov 19, 2010 at 03:21 pm

@Chris
oh, thank you, now I understood what you said above, and I just found out that the -moz-user-select inherited property automatically pass to the children.

27
.(JavaScript must be enabled to view this email address) commented on Nov 24, 2010 at 11:50 am

Thanks for this simple solution to an annoying problem. :)

28
.(JavaScript must be enabled to view this email address) commented on Jan 8, 2011 at 06:07 am

Ctrl + A (select all) work in opera, safari, chrome

How can disable Ctrl + A with jquery?

29
.(JavaScript must be enabled to view this email address) commented on Jun 29, 2011 at 01:26 pm

i developed an autogenerated text field in jquery and text is selected by double click on it .....it works well in IE7 but in firefox text is not selected by double clicking….....plz give me solution….!!

30
.(JavaScript must be enabled to view this email address) commented on Aug 22, 2011 at 10:25 am

In chrome, if you click outside the scope of the selected element, and drag into the selected element, you are able to select the text. Is there a fix for this?

31
.(JavaScript must be enabled to view this email address) commented on Jan 7, 2012 at 04:13 pm

Works Great! Thanks a lot!

32
.(JavaScript must be enabled to view this email address) commented on Jan 19, 2012 at 03:57 am

Very useful, thanks!

33
.(JavaScript must be enabled to view this email address) commented on May 15, 2012 at 03:40 am

Thank you very much. Your script is work well.

Post a Comment