Sélectionnez tout le texte DIV avec un seul clic de souris


136

Comment mettre en évidence / sélectionner le contenu d'une balise DIV lorsque l'utilisateur clique sur le DIV ... l'idée est que tout le texte est mis en surbrillance / sélectionné afin que l'utilisateur n'ait pas besoin de surligner manuellement le texte avec la souris et potentiellement manquer un peu du texte?

Par exemple, disons que nous avons un DIV comme ci-dessous:

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

... et lorsque l'utilisateur clique sur l'une de ces URL, tout le texte de l'URL est mis en surbrillance afin qu'il puisse facilement faire glisser le texte sélectionné dans le navigateur, ou copier l'URL complète avec un clic droit.

Merci!

Réponses:


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>

Vous devez maintenant passer l'ID comme argument, qui dans ce cas est "sélectionnable", mais il est plus global, vous permettant de l'utiliser n'importe où plusieurs fois sans utiliser, comme Chiborg l'a mentionné, jQuery.


8
BTW, vous pouvez facilement le transformer en un gestionnaire d'événements jQuery click remplaçant document.getElementById('selectable')par this. Ensuite, vous pouvez ajouter discrètement la fonctionnalité à plusieurs éléments, par exemple plusieurs divs dans un conteneur: jQuery('#selectcontainer div').click(selectText);
chiborg

3
Cela fonctionne correctement sur Chrome, FF, Safari (Mac) et Chrome et IE (Windows 9+, 8 non testé). Mais cela ne semble pas fonctionner sur Safari sur iPad Mini (iOS6) ou iPhone 4, pas sûr d'autres iOS ou Android.
prototype

1
Selon cet article, la requête if (window.getSelection) {devrait venir en premier pour Opera ( quirksmode.org/dom/range_intro.html )
prototype du

1
Cette solution ne semble pas fonctionner dans ie11. Une idée pourquoi?
Swiss Mister

5
Dans la version 36 de Chrome, cela renverra une erreur "La sélection discontinue n'est pas prise en charge". La solution est d'ajouter window.getSelection().removeAllRanges();avantwindow.getSelection().addRange(range);
nHaskins

122

MISE À JOUR 2017:

Pour sélectionner le contenu du nœud, appelez:

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

Cela fonctionne sur tous les navigateurs modernes, y compris IE9 + (en mode standard).

Exemple exécutable:

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 réponse originale ci-dessous est obsolète car window.getSelection().addRange(range); elle est obsolète

Réponse originale:

Tous les exemples ci-dessus utilisent:

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

mais le problème avec cela est qu'il sélectionne le nœud lui-même, y compris la balise DIV, etc.

Pour sélectionner le texte du nœud selon la question OP, vous devez appeler à la place:

    range.selectNodeContents( ... )

L'extrait complet serait donc:

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

Vous pouvez également utiliser thisau lieu d'obtenir l'élément en fonction de l'ID tant qu'il se trouve dans l' clickécouteur de l'élément .
Zach Saucier

44

Il existe une solution CSS4 pure:

.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-selectest une spécification du module CSS de niveau 4, qui est actuellement une propriété CSS brouillon et non standard, mais les navigateurs la prennent bien en charge - voir # search = user-select .

En savoir plus sur la sélection par l'utilisateur ici sur MDN et jouer avec ici dans w3scools


3
+1 solution élégante géniale géniale! Testé en septembre 2017 et fonctionne parfaitement sur FireFox et Chrome MAIS PAS DANS MICROSOFT EDGE !? Des idées pourquoi pas et comment résoudre ce problème? Merci!
Sam

13

La réponse de Neuroxik a été vraiment utile. Je n'ai eu qu'un problème avec Chrome, car lorsque j'ai cliqué sur un div externe, cela ne fonctionnait pas. Je pourrais le résoudre en supprimant les anciennes plages avant d'ajouter la nouvelle plage:

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

Pour le contenu modifiable (pas les entrées régulières, vous devez utiliser selectNodeContents (plutôt que simplement selectNode).

REMARQUE: Toutes les références à "document.selection" et "createTextRange ()" sont pour IE 8 et inférieur ... Vous n'aurez probablement pas besoin de prendre en charge ce monstre si vous essayez de faire des choses délicates comme celle-ci.

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

En utilisant un champ de zone de texte, vous pouvez utiliser ceci: (via 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>

C'est ainsi que je vois la plupart des sites Web le faire. Ils le stylisent simplement avec CSS pour qu'il ne ressemble pas à une zone de texte.


pourquoi pas juste this.focus();this.select();?
Taha Paksu le

5

Cet extrait de code fournit les fonctionnalités dont vous avez besoin . Ce que vous devez faire est d'ajouter un événement à ce div qui active fnSelect dans celui-ci. Un hack rapide que vous ne devriez absolument pas faire et qui pourrait ne pas fonctionner, ressemblerait à ceci:

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

En supposant évidemment que l'extrait lié à a été inclus.


5

J'ai trouvé utile d'envelopper cette fonction sous forme de 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);
        }
    });
}

Ainsi, cela devient une solution réutilisable. Ensuite, vous pouvez faire ceci:

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

Et il sera sélectionné test dans le div.


1
N'oubliez pas d'appeler window.getSelection (). RemoveAllRanges (); comme dans le code de Josillo. Aussi: je recommanderais de mettre window.getSelect comme première option, car il s'agit du standard HTML5 et document.selection est l'ancienne solution de secours IE pour IE8 et les versions antérieures.
Jan Aagaard

3

Et cette solution simple? :)

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

Bien sûr, ce n'est pas une construction div, comme vous l'avez mentionné, mais cela fonctionne pour moi.


1
Solution concise, mais cela ne tient pas compte du texte dans un élément autre qu'un champ d'entrée ou de zone de texte.
JoePC

3

Niko Lay: Et cette solution simple? :)

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

.....

Code avant:

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

Code après:

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

Juste cette partie onclick = "this.select ();" id = "sélectionnable" dans mon code a bien fonctionné. Sélectionne tout dans ma boîte de code avec un clic de souris.

Merci pour l'aide 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 réponse ci-dessus ne fonctionne pas dans Chrome, car addRange supprime la plage précédemment ajoutée. Je n'ai trouvé aucune solution pour cela à côté de la fausse sélection avec css.


Pour quelqu'un, ce code peut être utile car je l'ai testé et trouvé qu'il fonctionnait dans la dernière version de Chrome: $ .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 (). removeAllRanges (); window.getSelection (). addRange (plage);}}); }
Haider Abbas

0

Facilement réalisé avec la propriété css user-select définie sur all. Comme ça:

div.anyClass {
  user-select: all;
}

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.