111

I made a paging control and I noticed that while clicking on the buttons it is very easy to accidentally select the individual images and text. Is it possible to prevent this?

To clarify selecting I mean highlighting with the mouse. (Try dragging your mouse from one side of the screen to the other.)

If you try to highlight the text/controls in this grid it can't be selected. How is that done? Link

The Muffin Man
  • 19,585
  • 30
  • 119
  • 191
  • 1
    possible duplicate of http://stackoverflow.com/questions/2700000/how-to-disable-text-selection-using-jquery – kapa Mar 25 '11 at 07:55
  • 1
    another possible duplicate http://stackoverflow.com/questions/2326004/prevent-selection-in-html – Javi R Mar 25 '11 at 08:02

10 Answers10

132

dragging and selecting both initialize on a mouse down event and update on subsequent mouse moves. When you handle the events to begin dragging, or to follow the mouse, cancel the event's bubbling and override the default browser return:

something like this in your begin dragging mousedown and move handlers-

e=e || window.event;
pauseEvent(e);
function pauseEvent(e){
    if(e.stopPropagation) e.stopPropagation();
    if(e.preventDefault) e.preventDefault();
    e.cancelBubble=true;
    e.returnValue=false;
    return false;
}
kennebec
  • 102,654
  • 32
  • 106
  • 127
  • 23
    Yeah e.preventDefault() should be all you need in modern browsers. The rest of the code is redundant: window.event is for older versions of IE, but since those events don't have the preventDefault method and the return false is not returned at the pauseEvent function call... it doesn't do anything (not even in 2011). – Sjeiti Jun 29 '15 at 21:15
  • 32
    CSS: `user-select: none;` is what I use. No need for JS to solve this any more I should think – Drenai Dec 25 '17 at 19:16
  • 1
    @Drenai That also makes the content unselectable for good. Make sure you only apply that during dragging. – Farzad Yousefzadeh Jul 18 '21 at 09:19
  • @Farzad Yousefzadeh Nope, dragging doesn't factor into it. No need for icon/text of a button to be selectable – Drenai Jul 18 '21 at 13:20
  • 2
    @Drenai what do you mean by "dragging doesn't factor into it"? Dragging still invokes pointer events similar to text selection. Try applying `user-select: none` to an element and dragging over it. Sure there are elements that don't need to be selectable. All I'm saying is to mention the unwanted side effects of that line of CSS if used incautiously. – Farzad Yousefzadeh Jul 20 '21 at 08:13
  • @Farzad Yousefzadeh what you're describing isn't an unwanted side effect of `user-select: none`, that's just it's purpose – Drenai Jul 20 '21 at 10:31
  • 2
    @Drenai You're missing my actual point. My point was `user-select: none` disables text selection regardless of what state of dragging you're in. Using `preventDefault` on the correct pointer events only disables it during the dragging. – Farzad Yousefzadeh Jul 20 '21 at 12:19
  • Using `event.preventDefault();` might cause have a problem with `input`'s `onblur`. In case when we type some text in `input` and then start drag (`mousedown` with `preventDefault`) `input`'s `onblur` will not trigger. – Dmitry Kurmanov Aug 16 '21 at 07:44
  • @Drenai If I want to apply custom drag-click functionality on specific elements that shouldn't invoke further events on the page, then this solution is helpful – Shane Callanan Jul 29 '22 at 11:48
  • This prevents the element from becoming active which leads to some annoyances for styling- i.e. having styles while dragging. – Carson Crane Jul 15 '23 at 09:58
67

For dragging, you're capturing the mousedown and mousemove events. (And hopefully touchstart and touchmove events as well, to support touch interfaces.)

You'll need to call event.preventDefault() in both the down and move events in order to keep the browser from selecting text.

For example (using jQuery):

var mouseDown = false;
$(element).on('mousedown touchstart', function(event) {
  event.preventDefault();
  mouseDown = true;
});
$(element).on('mousemove touchmove', function(event) {
  event.preventDefault();
  if(mouseDown) {
    // Do something here.
  }
});
$(window.document).on('mouseup touchend', function(event) {
  // Capture this event anywhere in the document, since the mouse may leave our element while mouse is down and then the 'up' event will not fire within the element.
  mouseDown = false;
});
Robin Daugherty
  • 7,115
  • 4
  • 45
  • 59
  • Thanks Robin, out of curiosity is there a difference between `window.document` and `window` or just `document`? I'm pretty sure `document` is a child of `window`.. – The Muffin Man Oct 03 '13 at 17:39
  • 1
    `window` is the outermost scope in which Javascript runs in the browser. So any variable not declared inside a function is a property of `window`. Referencing `document` directly is actually referring to `window.document`. – Robin Daugherty Oct 09 '13 at 23:37
  • 4
    As far as I can tell it suffices to cancel default on only the "mousedown" event. – tremby Feb 04 '17 at 02:36
48

This is a very old post. It may not answer exactly that situation, but i use CSS for my solution:

-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
Mike
  • 649
  • 1
  • 12
  • 17
19

I wanted to comment, but i don't have enough reputation. Using the suggested function from @kennebec solved my problem in my javascript dragging library. It works flawlessy.

function pauseEvent(e){
    if(e.stopPropagation) e.stopPropagation();
    if(e.preventDefault) e.preventDefault();
    e.cancelBubble=true;
    e.returnValue=false;
    return false;
}

i called it in my mousedown and mousemove custom function, immediately after i can recognize i clicked on the right element. If i call it just on top of the function i just kill any click on the document. My function is registered as an event on document.body.

AndreaBogazzi
  • 14,323
  • 3
  • 38
  • 63
10

try this:

document.onselectstart = function()
{
    window.getSelection().removeAllRanges();
};
Alex Pacurar
  • 5,801
  • 4
  • 26
  • 33
9

This can be achieved using CSS in most browsers and the unselectable expando in IE. See my answer here: How to disable text selection highlighting using CSS?

Community
  • 1
  • 1
Tim Down
  • 318,141
  • 75
  • 454
  • 536
1

If you need to block text selection for a certain element using JavaScript, then the simplest method for me was to assign userSelect style like this:

var myElement = document.createElement('div');
myElement.style.userSelect = 'none';
Erkki Teedla
  • 309
  • 2
  • 8
0

simply prevent it by calling blur() function when selected as following :

 <input Value="test" onSelect="blur();">
Mehdi
  • 9
  • 1
0

Just paste this code in your JavaScript somewhere

document.onmousemove = function(evt){
 event.preventDefault();
}

I debugged that just now on https://www.colorzilla.com/gradient-editor/ and tested it in the console and it worked, no more unwanted UI selection...

no_one
  • 19
  • 7
0

Something working well for me is to preventDefault on the mousemove event unless an onselectstart event is fired.

const handler = event => event.preventDefault();

document.onmousedown = () => document.addEventListener("mousemove", handler);
document.onmouseup = () => document.removeEventListener("mousemove", handler);
document.onselectstart = () => document.removeEventListener("mousemove", handler);

This allows me to still handle text selection correctly on elements with user-select: auto.

11 years later, I hope this helps someone!

prozac
  • 239
  • 2
  • 5