Wählen Sie den gesamten DIV-Text mit einem einzigen Mausklick aus

135

So markieren / wählen Sie den Inhalt eines DIV-Tags aus, wenn der Benutzer auf das DIV klickt ... Die Idee ist, dass der gesamte Text hervorgehoben / ausgewählt wird, sodass der Benutzer den Text nicht manuell mit der Maus und möglicherweise markieren muss Vermissen Sie einen Teil des Textes?

Angenommen, wir haben einen DIV wie folgt:

<div id="selectable">http://example.com/page.htm</div>

... und wenn der Benutzer auf eine dieser URLs klickt, wird der gesamte URL-Text hervorgehoben, sodass er den ausgewählten Text einfach im Browser verschieben oder die vollständige URL mit einem Rechtsklick kopieren kann.

Vielen Dank!

Acyra
quelle

Antworten:

192

function selectText(containerid) {
    if (document.selection) { // IE
        var range = document.body.createTextRange();
        range.moveToElementText(document.getElementById(containerid));
        range.select();
    } else if (window.getSelection) {
        var range = document.createRange();
        range.selectNode(document.getElementById(containerid));
        window.getSelection().removeAllRanges();
        window.getSelection().addRange(range);
    }
}
<div id="selectable" onclick="selectText('selectable')">http://example.com/page.htm</div>

Jetzt müssen Sie die ID als Argument übergeben, das in diesem Fall "auswählbar" ist, aber globaler, sodass Sie sie überall mehrfach verwenden können, ohne, wie von Chiborg erwähnt, jQuery zu verwenden.

Denis Sadowski
quelle
8
BTW, können Sie einfach diese wiederum in einem Event - Handler jQuery Klick ersetzen document.getElementById('selectable')mit this. Dann können Sie die Funktionalität unauffällig mehreren Elementen hinzufügen, zum Beispiel mehreren Divs in einem Container: jQuery('#selectcontainer div').click(selectText);
Chiborg
3
Dies funktioniert gut unter Chrome, FF, Safari (Mac) und Chrome und IE (Windows 9+, 8 nicht getestet). Aber es scheint nicht auf Safari auf dem iPad Mini (iOS6) oder iPhone 4 zu funktionieren, nicht sicher über andere iOS oder Android.
Prototyp
1
Gemäß diesem Artikel sollte die Abfrage if (window.getSelection) {für Opera ( quirksmode.org/dom/range_intro.html ) an erster Stelle stehen
Prototyp
1
Diese Lösung scheint in ie11 nicht zu funktionieren. Irgendeine Idee warum?
Schweizer Herr
5
In Chrome Version 36+ wird der Fehler "Nicht zusammenhängende Auswahl wird nicht unterstützt" zurückgegeben. Die Lösung ist, window.getSelection().removeAllRanges();vorwindow.getSelection().addRange(range);
nHaskins
121

UPDATE 2017:

So wählen Sie den Inhalt des Knotens aus:

window.getSelection().selectAllChildren(
    document.getElementById(id)
);

Dies funktioniert in allen modernen Browsern einschließlich IE9 + (im Standardmodus).

Ausführbares Beispiel:

function select(id) {
  window.getSelection()
    .selectAllChildren(
      document.getElementById("target-div") 
    );
}
#outer-div  { padding: 1rem; background-color: #fff0f0; }
#target-div { padding: 1rem; background-color: #f0fff0; }
button      { margin: 1rem; }
<div id="outer-div">
  <div id="target-div">
    Some content for the 
    <br>Target DIV
  </div>
</div>

<button onclick="select(id);">Click to SELECT Contents of #target-div</button>


Die ursprüngliche Antwort unten ist veraltet, da window.getSelection().addRange(range); sie veraltet ist

Ursprüngliche Antwort:

Alle obigen Beispiele verwenden:

    var range = document.createRange();
    range.selectNode( ... );

Das Problem dabei ist jedoch, dass der Knoten selbst einschließlich des DIV-Tags usw. ausgewählt wird.

Um den Text des Knotens gemäß der OP-Frage auszuwählen, müssen Sie stattdessen Folgendes aufrufen:

    range.selectNodeContents( ... )

Das vollständige Snippet wäre also:

    function selectText( containerid ) {

        var node = document.getElementById( containerid );

        if ( document.selection ) {
            var range = document.body.createTextRange();
            range.moveToElementText( node  );
            range.select();
        } else if ( window.getSelection ) {
            var range = document.createRange();
            range.selectNodeContents( node );
            window.getSelection().removeAllRanges();
            window.getSelection().addRange( range );
        }
    }
Isapir
quelle
Sie können thisdas Element auch verwenden, anstatt es anhand der ID abzurufen, solange es sich im clickListener des Elements befindet .
Zach Saucier
44

Es gibt eine reine CSS4-Lösung:

.selectable{
    -webkit-touch-callout: all; /* iOS Safari */
    -webkit-user-select: all; /* Safari */
    -khtml-user-select: all; /* Konqueror HTML */
    -moz-user-select: all; /* Firefox */
    -ms-user-select: all; /* Internet Explorer/Edge */
    user-select: all; /* Chrome and Opera */

}

user-selectist eine CSS-Modul-Level-4-Spezifikation, die derzeit ein Entwurf und eine nicht standardmäßige CSS-Eigenschaft ist, aber von Browsern gut unterstützt wird - siehe # search = user-select .

Lesen Sie mehr über die Benutzerauswahl hier auf MDN und spielen Sie hier in w3scools damit

Mino
quelle
3
+1 super genial elegante Lösung! Getestet im September 2017 und es funktioniert einwandfrei auf FireFox und Chrome, ABER NICHT IN MICROSOFT EDGE!? Irgendwelche Ideen warum nicht und wie man das behebt? Vielen Dank!
Sam
13

Die Antwort von Neuroxik war wirklich hilfreich. Ich hatte nur ein Problem mit Chrome, denn als ich auf ein externes Div klickte, funktionierte es nicht. Ich könnte es lösen, indem ich die alten Bereiche entferne, bevor ich den neuen Bereich hinzufüge:

function selectText(containerid) {
    if (document.selection) {
        var range = document.body.createTextRange();
        range.moveToElementText(document.getElementById(containerid));
        range.select();
    } else if (window.getSelection()) {
        var range = document.createRange();
        range.selectNode(document.getElementById(containerid));
        window.getSelection().removeAllRanges();
        window.getSelection().addRange(range);
    }
}
<div id="selectable" onclick="selectText('selectable')">http://example.com/page.htm</div>
Josillo Debian
quelle
9

Für inhaltsbearbeitbare Inhalte (keine regulären Eingaben) müssen Sie selectNodeContents verwenden (und nicht nur selectNode).

HINWEIS: Alle Verweise auf "document.selection" und "createTextRange ()" gelten für IE 8 und niedriger ... Sie müssen dieses Monster wahrscheinlich nicht unterstützen, wenn Sie versuchen, solche kniffligen Dinge zu tun.

function selectElemText(elem) {

    //Create a range (a range is a like the selection but invisible)
    var range = document.createRange();

    // Select the entire contents of the element
    range.selectNodeContents(elem);

    // Don't select, just positioning caret:
    // In front 
    // range.collapse();
    // Behind:
    // range.collapse(false);

    // Get the selection object
    var selection = window.getSelection();

    // Remove any current selections
    selection.removeAllRanges();

    // Make the range you have just created the visible selection
    selection.addRange(range);

}
Bob
quelle
6

Wenn Sie ein Textfeld verwenden, können Sie Folgendes verwenden: (Über Google)

<form name="select_all">

    <textarea name="text_area" rows="10" cols="80" 
    onClick="javascript:this.form.text_area.focus();this.form.text_area.select();">

    Text Goes Here 

    </textarea>
</form>

So sehe ich die meisten Websites. Sie stylen es einfach mit CSS, damit es nicht wie ein Textbereich aussieht.

Tyler Carter
quelle
warum nicht einfach this.focus();this.select();?
Taha Paksu
5

Dieses Snippet bietet die Funktionalität, die Sie benötigen . Was Sie tun müssen, ist ein Ereignis zu dem Div hinzuzufügen, das fnSelect darin aktiviert. Ein schneller Hack, den Sie absolut nicht ausführen sollten und der möglicherweise nicht funktioniert, würde folgendermaßen aussehen:

document.getElementById("selectable").onclick(function(){
    fnSelect("selectable");
});

Offensichtlich unter der Annahme, dass das mit dem Snippet verknüpfte Element enthalten war.

Simon Scarfe
quelle
5

Ich fand es nützlich, diese Funktion als jQuery-Plugin zu verpacken:

$.fn.selectText = function () {
    return $(this).each(function (index, el) {
        if (document.selection) {
            var range = document.body.createTextRange();
            range.moveToElementText(el);
            range.select();
        } else if (window.getSelection) {
            var range = document.createRange();
            range.selectNode(el);
            window.getSelection().addRange(range);
        }
    });
}

So wird es eine wiederverwendbare Lösung. Dann können Sie dies tun:

<div onclick="$(this).selectText()">http://example.com/page.htm</div>

Und es wird Test in der div ausgewählt.

Vitmalina
quelle
1
Denken Sie daran, window.getSelection () aufzurufen. RemoveAllRanges (); wie in Josillos Code. Außerdem: Ich würde empfehlen, window.getSelect als erste Option zu verwenden, da dies der HTML5-Standard ist und document.selection der alte IE-Fallback für IE8 und früher ist.
Jan Aagaard
3

Wie wäre es mit dieser einfachen Lösung? :) :)

<input style="background-color:white; border:1px white solid;" onclick="this.select();" id="selectable" value="http://example.com/page.htm">

Sicher, es ist keine Div-Konstruktion, wie Sie erwähnt haben, aber es funktioniert trotzdem für mich.

Niko Lay
quelle
1
Prägnante Lösung, aber dies berücksichtigt keinen Text in einem anderen Element als einem Eingabe- oder Textfeld.
JoePC
3

Niko Lay: Wie wäre es mit dieser einfachen Lösung? :) :)

`<input style="background-color:white; border:1px white solid;" onclick="this.select();" id="selectable" value="http://example.com/page.htm">`

..... .....

Code vor:

<textarea rows="20" class="codearea" style="padding:5px;" readonly="readonly">

Code nach:

<textarea rows="20" class="codearea" style="padding:5px;" readonly="readonly" onclick="this.select();" id="selectable">

Nur dieser Teil onclick = "this.select ();" id = "auswählbar" in meinem Code hat gut funktioniert. Wählt alle in meinem Codefeld mit einem Mausklick aus.

Danke für die Hilfe Niko Lay!

Igor B.
quelle
0
$.fn.selectText = function () {
    return $(this).each(function (index, el) {
        if (document.selection) {
            var range = document.body.createTextRange();
            range.moveToElementText(el);
            range.select();
        } else if (window.getSelection) {
            var range = document.createRange();
            range.selectNode(el);
            window.getSelection().addRange(range);
        }
    });
}

Die obige Antwort funktioniert in Chrome nicht, da addRange den zuvor hinzugefügten Bereich entfernt. Ich habe keine Lösung dafür gefunden, abgesehen von einer falschen Auswahl mit CSS.

Christopher Gibała
quelle
Für jemanden kann dieser Code hilfreich sein, da ich ihn in der neuesten Version von Chrome getestet und als funktionsfähig befunden habe: $ .fn.selectText = function () {return $ (this) .each (function (index, el) {if (document. Auswahl) {var range = document.body.createTextRange (); range.moveToElementText (el); range.select ();} else if (window.getSelection) {var range = document.createRange (); range.selectNode (el ); window.getSelection (). removeAllRanges (); window.getSelection (). addRange (range);}}); }
Haider Abbas
0

Einfach zu erreichen, wenn die CSS-Eigenschaft user-select auf all gesetzt ist. So was:

div.anyClass {
  user-select: all;
}

tirmey
quelle