Seleziona tutto il testo DIV con un solo clic del mouse


136

Come evidenziare / selezionare il contenuto di un tag DIV quando l'utente fa clic sul DIV ... l'idea è che tutto il testo sia evidenziato / selezionato in modo che l'utente non debba evidenziare manualmente il testo con il mouse e potenzialmente perdere un po 'di testo?

Ad esempio, supponiamo di avere un DIV come di seguito:

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

... e quando l'utente fa clic su uno di questi URL viene evidenziato l'intero testo dell'URL in modo da poter facilmente trascinare il testo selezionato nel browser o copiare l'URL completo con un clic destro.

Grazie!

Risposte:


194

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>

Ora devi passare l'ID come argomento, che in questo caso è "selezionabile", ma è più globale, permettendoti di usarlo ovunque più volte senza usare, come ha detto Chiborg, jQuery.


8
A proposito, si può facilmente trasformare questo in un gestore di eventi jQuery click sostituzione document.getElementById('selectable')con this. Quindi puoi aggiungere la funzionalità in modo discreto a diversi elementi, ad esempio diversi div in un contenitore: jQuery('#selectcontainer div').click(selectText);
chiborg

3
Funziona bene su Chrome, FF, Safari (Mac) e Chrome e IE (Windows 9+, 8 non testato). Ma non sembra funzionare su Safari su iPad Mini (iOS6) o iPhone 4, non sono sicuro di altri iOS o Android.
prototipo

1
Per questo articolo, la query if (window.getSelection) {dovrebbe venire prima per Opera ( quirksmode.org/dom/range_intro.html )
prototipo

1
Questa soluzione sembra non funzionare in ie11. Qualche idea sul perché?
Swiss Mister,

5
Nella versione 36+ di Chrome verrà restituito un errore "La selezione non contigua non è supportata". La soluzione è aggiungere window.getSelection().removeAllRanges();primawindow.getSelection().addRange(range);
nHaskins il

122

AGGIORNAMENTO 2017:

Per selezionare la chiamata del contenuto del nodo:

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

Funziona su tutti i browser moderni incluso IE9 + (in modalità standard).

Esempio eseguibile:

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>


La risposta originale di seguito è obsoleta poiché window.getSelection().addRange(range); è stata deprecata

Risposta originale:

Tutti gli esempi sopra usano:

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

ma il problema è che seleziona il nodo stesso incluso il tag DIV ecc.

Per selezionare il testo del nodo in base alla domanda OP, è necessario chiamare invece:

    range.selectNodeContents( ... )

Quindi lo snippet completo sarebbe:

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

Puoi anche utilizzare thisinvece di ottenere l'elemento in base all'ID purché sia ​​all'interno del clicklistener dell'elemento .
Zach Saucier,

44

Esiste una soluzione CSS4 pura:

.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-selectè una specifica di livello 4 del modulo CSS, che è attualmente una proprietà CSS non standard e bozza, ma i browser la supportano bene - vedi # search = user-select .

Leggi di più su seleziona l'utente qui su MDN e gioca qui su w3scools


3
+1 fantastica fantastica soluzione elegante! Testato a settembre 2017 e funziona perfettamente su FireFox e Chrome MA NON IN BORDO MICROSOFT !? Qualche idea perché no e come risolverlo? Grazie!
Sam,

13

La risposta di Neuroxik è stata davvero utile. Ho avuto solo un problema con Chrome, perché quando ho fatto clic su un div esterno, non funzionava. Potrei risolverlo rimuovendo i vecchi intervalli prima di aggiungere il nuovo intervallo:

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>

9

Per contenuti modificabili (non input regolari, è necessario utilizzare selectNodeContents (anziché solo selectNode).

NOTA: tutti i riferimenti a "document.selection" e "createTextRange ()" sono per IE 8 e precedenti ... Probabilmente non dovrai supportare quel mostro se stai tentando di fare cose difficili come questa.

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

}

6

Utilizzando un campo area di testo, è possibile utilizzare questo: (tramite 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>

Questo è come vedo la maggior parte dei siti Web farlo. Lo modellano semplicemente con CSS in modo che non sembri una textarea.


perché non solo this.focus();this.select();?
Taha Paksu,

5

Questo frammento fornisce le funzionalità richieste . Quello che devi fare è aggiungere un evento a quel div ciò che attiva fnSeleziona in esso. Un trucco rapido che non dovresti assolutamente fare e che forse non funziona, potrebbe apparire così:

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

Ovviamente supponendo che fosse stato incluso il link al frammento.


5

Ho trovato utile avvolgere questa funzione come plugin jQuery:

$.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);
        }
    });
}

Quindi, diventa una soluzione riutilizzabile. Quindi puoi farlo:

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

E selezionerà il test nel div.


1
Ricorda di chiamare window.getSelection (). RemoveAllRanges (); come nel codice di Josillo. Inoltre: consiglierei di inserire window.getSelect come prima opzione, poiché si tratta dello standard HTML5 e document.selection è il vecchio fallback di IE per IE8 e precedenti.
Jan Aagaard,

3

Che ne dici di questa semplice soluzione? :)

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

Certo non è div-construction, come hai già detto, ma funziona ancora per me.


1
Soluzione concisa, ma questo non tiene conto del testo in un elemento diverso da un campo di input o textarea.
JoePC,

3

Niko Lay: che ne dici di questa semplice soluzione? :)

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

.....

Codice prima di:

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

Codice dopo:

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

Solo questa parte onclick = "this.select ();" id = "selezionabile" nel mio codice ha funzionato bene. Seleziona tutto nella mia casella di codice con un clic del mouse.

Grazie per l'aiuto Niko Lay!


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

La risposta sopra non funziona in Chrome perché addRange rimuove l'intervallo aggiunto precedente. Non ho trovato alcuna soluzione per questo oltre alla falsa selezione con CSS.


Per qualcuno questo codice può essere utile come ho testato e trovato funzionante nell'ultima versione di Chrome: $ .fn.selectText = function () {return $ (this) .each (function (index, el) {if (document. selezione) {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

Facilmente raggiungibile con la proprietà css user-select impostata su all. Come questo:

div.anyClass {
  user-select: all;
}

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.