Zapobiegaj zaznaczaniu tekstu po podwójnym kliknięciu

294

Obsługuję zdarzenie dblclick w zakresie w mojej aplikacji internetowej. Efektem ubocznym jest to, że podwójne kliknięcie zaznacza tekst na stronie. Jak mogę zapobiec tej selekcji?

David
źródło

Odpowiedzi:

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

Możesz także zastosować te style do zakresu dla wszystkich przeglądarek innych niż IE i 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+ */
}
Paolo Bergantino
źródło
44
Czy jest jakiś sposób, aby faktycznie zapobiec selekcji, a nie usunąć ją po fakcie? Również druga instrukcja if może znajdować się w reszcie, jeśli dla lepszej czytelności.
David
8
Najlepiej używać prefiksu -webkit- (jest to preferowany prefiks dla przeglądarek opartych na Webkit) oprócz -moz- (i -khtml-, jeśli masz dużą grupę odbiorców Konquerora).
powiek
3
To jest teraz dostępne w IE10, -ms-user-select: none;patrz blogs.msdn.com/b/ie/archive/2012/01/11/… @PaoloBergantino
cytryna
1
@TimHarper: Oczywiście jeśli chodzi o rozwiązania JavaScript korzystające z biblioteki. Nie bardzo wiem, dlaczego uzasadnia to głosowanie negatywne.
Paolo Bergantino,
14
Istnieje różnica między wyłączeniem zaznaczenia przy podwójnym kliknięciu a całkowitym wyłączeniem. Pierwszy zwiększa użyteczność. Drugi maleje.
Robo Robok,
112

Prostym javascript:

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

Lub z jQuery:

jQuery(element).mousedown(function(e){ e.preventDefault(); });
Tomek
źródło
26
Tak, kiedyś rozwiązać ten sam problem miałem posiadającą (+1), z wyjątkiem zamiast return falseużywanych event.preventDefault(), które nie zabija wszelkie inne ładowarki mogą mieć na mousedown.
Simon East
2
To łamie elementy textarea na stronie :(
John ktejik
1
@ johnktejik tylko wtedy, gdy elementjest to obszar tekstowy , tak.
fregante
11
Spodziewałbym się przypisania tego programu obsługi zdarzeń do „dblclick” - ale to nie działa, co jest takie dziwne. W przypadku „mousedown” oczywiście nie można również zaznaczać tekstu przez przeciąganie.
corwin.amber
74

Aby zapobiec zaznaczaniu tekstu TYLKO po podwójnym kliknięciu:

Możesz użyć MouseEvent#detailnieruchomości. W przypadku zdarzeń mousedown lub mouseup jest to 1 plus bieżąca liczba kliknięć.

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);

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

4esn0k
źródło
4
To jest niesamowite! Działa w przeglądarce Firefox 53.
Zaroth
6
To powinna być zaakceptowana odpowiedź. Wszystko inne tutaj zapobiega wybraniu myszy (lub gorzej) zamiast odpowiedzi na pytanie OP „ Zapobiegaj
zaznaczaniu
1
Działa również w Chrome
KS74
1
Działa również na IE 11 Windows 10 =). Dzięki za udostępnienie tego.
Fernando Vieira
Użyj, (event.detail === 2)aby naprawdę zapobiec TYLKO podwójnemu kliknięciu (a nie potrójnemu kliknięciu itp.)
Robin Stewart
32

FWIW, zestaw user-select: nonedo elementu nadrzędnego tych elementów podrzędnych, które nie chcę jakoś wybrany, gdy podwójne kliknięcie w dowolnym miejscu elementu nadrzędnego. I to działa! Fajne jest to contenteditable="true", że zaznaczanie tekstu itp. Nadal działa na elementach potomnych!

Tak jak:

<div style="user-select: none">
  <p>haha</p>
  <p>haha</p>
  <p>haha</p>
  <p>haha</p>
</div>
kyw
źródło
Dzięki, pieprzenie style="user-select: note"wszędzie rozwiązało problem, który próbowałem rozwiązać :)
esaruoho
Ładne rozwiązanie tylko dla css dla przypadków, w których zasadniczo nie chcesz, aby tekst był zaznaczalny. Dzięki!
Ian Lovejoy
11

Prosta funkcja JavaScript, która sprawia, że ​​zawartość wewnątrz elementu strony jest niemożliwa do wybrania:

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";
  }
}

źródło
4

Dla tych, którzy szukają rozwiązania dla Angular 2+ .

Możesz użyć danych mousedownwyjściowych komórki tabeli.

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

I zapobiec, jeśli 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 ...
}

Dane dblclickwyjściowe nadal działają zgodnie z oczekiwaniami.

bvdb
źródło
3

lub na mozilli:

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

W IE

document.body.onmousedown = function() { return false; } // valid for any html object as well
José Leal
źródło
5
To rozwiązanie nie pozwala wcale na zaznaczanie tekstu.
jmav
1
@jmav Musiałbyś zastosować przesłonięcia funkcji na bardziej konkretnym elemencie niż document.body.
Cypher,
2

Stary wątek, ale wymyśliłem rozwiązanie, które moim zdaniem jest czystsze, ponieważ nie wyłącza wszystkich równych wiązań z obiektem, a jedynie zapobiega losowym i niechcianym zaznaczeniom tekstu na stronie. To jest proste i działa dobrze dla mnie. Oto przykład; Chcę zapobiec zaznaczaniu tekstu, gdy kliknę kilka razy na obiekcie klasą „strzałka w prawo”:

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

HTH!

nncho
źródło
1

Jeśli próbujesz całkowicie zapobiec zaznaczaniu tekstu dowolną metodą, a także tylko podwójnym kliknięciem, możesz użyć user-select: noneatrybutu css. Testowałem w Chrome 68, ale zgodnie z https://caniuse.com/#search=user-select powinien on działać w innych przeglądarkach zwykłych użytkowników.

Zachowawczo, w Chrome 68 jest dziedziczony przez elementy potomne i nie pozwalał na zaznaczenie tekstu zawierającego element, nawet jeśli zaznaczono tekst otaczający i obejmujący element.

stackuser83
źródło
0

Aby zapobiec IE 8 CTRL i SHIFT, kliknij zaznaczanie tekstu na poszczególnych elementach

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

Aby zapobiec zaznaczaniu tekstu w dokumencie

window.onload = function(){
  document.onselectstart = function(){
    return false;
  }
}
rajesh
źródło
-2

Miałem ten sam problem. Rozwiązałem go, przełączając się na <a>i dodając onclick="return false;"(aby kliknięcie go nie dodawało nowego wpisu do historii przeglądarki).

minhle_r7
źródło