David
David

Reputation: 7817

Prevent text selection after double click

I'm handling the dblclick event on a span in my web app. A side effect of a double click is that it selects text on the page. How can I prevent this selection from happening?

Upvotes: 382

Views: 196728

Answers (16)

David K
David K

Reputation: 1

If you encounter a situation with an HTML details element where clicking too fast when opening it cause all text inside to be selected, you can simply add user-select: none; to the summary element. This prevents the contents from being selected when opening it, but still allows you to select contents within the open element.

<details>
    <summary style="user-select: none;"> </summary>
        //contents here won't be selected
</details>

Upvotes: 0

Axonile Plus
Axonile Plus

Reputation: 17

CSS is enough :

<style>
    #noselect{user-select: none;}
</style>
<div id="noselect"> NON SELECTABLE </div>

Upvotes: -1

4esn0k
4esn0k

Reputation: 10465

To prevent text selection ONLY after a double click:

You could use MouseEvent#detail property. For mousedown or mouseup events, it is 1 plus the current click count.

document.addEventListener('mousedown', function(event) {
  if (event.detail > 1) {
    event.preventDefault();
    // of course, you still do not know what you prevent here...
    // You could also check event.ctrlKey/event.shiftKey/event.altKey
    // to not prevent something useful.
  }
}, false);
Some dummy text

See https://developer.mozilla.org/en-US/docs/Web/API/UIEvent/detail

Upvotes: 172

John Smith
John Smith

Reputation: 1886

Tailwind CSS:

<div class="select-none ...">
  This text is not selectable
</div>

Upvotes: 0

ackh
ackh

Reputation: 2052

I know this is an old question but it is still perfectly valid in 2021. However, what I'm missing in terms of answers is any mentioning of Event.stopPropagation().

The OP is asking for the dblclick event but from what I see the same problem occurs with the pointerdown event. In my code I register a listener as follows:

this.addEventListener("pointerdown", this._pointerDownHandler.bind(this));

The listener code looks as follows:

_pointerDownHandler(event) {
  // Stuff that needs to be done whenever a click occurs on the element
}

Clicking fast multiple times on my element gets interpreted by the browser as double click. Depending on where your element is located on the page that double click will select text because that is the given behavior.

You could disable that default action by invoking Event.preventDefault() in the listener which does solve the problem, at least in a way.

However, if you register a listener on an element and write the corresponding "handling" code you might as well swallow that event which is what Event.stopPropagation() ensures. Therefore, the handler would look as follows:

_pointerDownHandler(event) {
  event.stopPropagation();
  // Stuff that needs to be done whenever a click occurs on the element
}

Because the event has been consumed by my element, elements further up the hierarchy are not aware of that event and won't execute their handling code.

If you let the event bubble up, elements higher in the hierarchy would all execute their handling code but are be told to not do so by Event.preventDefault() which makes less sense to me than preventing the event from bubbling up in the first place.

Upvotes: 0

Valeri Tonchev
Valeri Tonchev

Reputation: 115

If you are using Vue JS, just append @mousedown.prevent="" to your element and it is magically going to disappear !

Upvotes: 3

Paolo Bergantino
Paolo Bergantino

Reputation: 488734

function clearSelection() {
    if(document.selection && document.selection.empty) {
        document.selection.empty();
    } else if(window.getSelection) {
        var sel = window.getSelection();
        sel.removeAllRanges();
    }
}

You can also apply these styles to the span for all non-IE browsers and IE10:

span.no_selection {
    user-select: none; /* standard syntax */
    -webkit-user-select: none; /* webkit (safari, chrome) browsers */
    -moz-user-select: none; /* mozilla browsers */
    -khtml-user-select: none; /* webkit (konqueror) browsers */
    -ms-user-select: none; /* IE10+ */
}

Upvotes: 412

bvdb
bvdb

Reputation: 24800

For those looking for a solution for Angular 2+.

You can use the mousedown output of the table cell.

<td *ngFor="..."
    (mousedown)="onMouseDown($event)"
    (dblclick) ="onDblClick($event)">
  ...
</td>

And prevent if the detail > 1.

public onMouseDown(mouseEvent: MouseEvent) {
  // prevent text selection for dbl clicks.
  if (mouseEvent.detail > 1) mouseEvent.preventDefault();
}

public onDblClick(mouseEvent: MouseEvent) {
 // todo: do what you really want to do ...
}

The dblclick output continues to work as expected.

Upvotes: 10

kyw
kyw

Reputation: 7555

FWIW, I set user-select: none to the parent element of those child elements that I don't want somehow selected when double clicking anywhere on the parent element. And it works! Cool thing is contenteditable="true", text selection and etc. still works on the child elements!

So like:

<div style="user-select: none">
  <p>haha</p>
  <p>haha</p>
  <p>haha</p>
  <p>haha</p>
</div>

Upvotes: 75

stackuser83
stackuser83

Reputation: 2240

If you are trying to completely prevent selecting text by any method as well as on a double click only, you can use the user-select: none css attribute. I have tested in Chrome 68, but according to https://caniuse.com/#search=user-select it should work in the other current normal user browsers.

Behaviorally, in Chrome 68 it is inherited by child elements, and did not allow selecting an element's contained text even if when text surrounding and including the element was selected.

Upvotes: 5

minhle_r7
minhle_r7

Reputation: 872

I had the same problem. I solved it by switching to <a> and add onclick="return false;" (so that clicking on it won't add a new entry to browser history).

Upvotes: -5

nncho
nncho

Reputation: 165

Old thread, but I came up with a solution that I believe is cleaner since it does not disable every even bound to the object, and only prevent random and unwanted text selections on the page. It is straightforward, and works well for me. Here is an example; I want to prevent text-selection when I click several time on the object with the class "arrow-right":

$(".arrow-right").hover(function(){$('body').css({userSelect: "none"});}, function(){$('body').css({userSelect: "auto"});});

HTH !

Upvotes: 0

Tom
Tom

Reputation: 1265

In plain javascript:

element.addEventListener('mousedown', function(e){ e.preventDefault(); }, false);

Or with jQuery:

jQuery(element).mousedown(function(e){ e.preventDefault(); });

Upvotes: 124

rajesh
rajesh

Reputation: 382

To prevent IE 8 CTRL and SHIFT click text selection on individual element

var obj = document.createElement("DIV");
obj.onselectstart = function(){
  return false;
}

To prevent text selection on document

window.onload = function(){
  document.onselectstart = function(){
    return false;
  }
}

Upvotes: 0

Daniel
Daniel

Reputation:

A simple Javascript function that makes the content inside a page-element unselectable:

function makeUnselectable(elem) {
  if (typeof(elem) == 'string')
    elem = document.getElementById(elem);
  if (elem) {
    elem.onselectstart = function() { return false; };
    elem.style.MozUserSelect = "none";
    elem.style.KhtmlUserSelect = "none";
    elem.unselectable = "on";
  }
}

Upvotes: 10

Jos&#233; Leal
Jos&#233; Leal

Reputation: 8109

or, on mozilla:

document.body.onselectstart = function() { return false; } // Or any html object

On IE,

document.body.onmousedown = function() { return false; } // valid for any html object as well

Upvotes: 1

Related Questions