Sélection de texte dans un élément (similaire à la mise en évidence avec votre souris)

Je voudrais que les utilisateurs cliquent sur un lien, puis il sélectionne le texte HTML dans un autre élément ( pas une entrée).

Par “select”, je veux dire de la même manière que vous sélectionneriez du texte en faisant glisser votre souris dessus. Cela a été un atout pour la recherche parce que tout le monde parle de “select” ou “highlight” en d’autres termes.

Est-ce possible? Mon code jusqu’à présent:

HTML:

Select Code Some Code here  

JS:

 function SelectText(element) { $("#" + element).select(); } 

Est-ce que je manque quelque chose de flagrant?

Javascript simple

 function selectText(node) { node = document.getElementById(node); if (document.body.createTextRange) { const range = document.body.createTextRange(); range.moveToElementText(node); range.select(); } else if (window.getSelection) { const selection = window.getSelection(); const range = document.createRange(); range.selectNodeContents(node); selection.removeAllRanges(); selection.addRange(range); } else { console.warn("Could not select text in node: Unsupported browser."); } } const clickable = document.querySelector('.click-me'); clickable.addEventListener('click', () => selectText('target')); 
 

Some text goes here!

Moar text!

Click me!

Voici une version sans reniflage de navigateur et sans confiance dans jQuery:

 function selectElementText(el, win) { win = win || window; var doc = win.document, sel, range; if (win.getSelection && doc.createRange) { sel = win.getSelection(); range = doc.createRange(); range.selectNodeContents(el); sel.removeAllRanges(); sel.addRange(range); } else if (doc.body.createTextRange) { range = doc.body.createTextRange(); range.moveToElementText(el); range.select(); } } selectElementText(document.getElementById("someElement")); selectElementText(elementInIframe, iframe.contentWindow); 

Le code de Jason ne peut pas être utilisé pour les éléments à l’intérieur d’un iframe (car la scope diffère de celle de la fenêtre et du document). J’ai corrigé ce problème et je l’ai modifié pour être utilisé comme tout autre plugin jQuery (chaînable):

Exemple 1: Sélection de tout le texte à l’intérieur des balises avec un seul clic et ajout de la classe "selected":

 $(function() { $("code").click(function() { $(this).selText().addClass("selected"); }); }); 

Exemple 2: En cliquant sur le bouton, sélectionnez un élément dans une Iframe:

 $(function() { $("button").click(function() { $("iframe").contents().find("#selectme").selText(); }); }); 

Remarque: n'oubliez pas que la source iframe doit résider dans le même domaine pour éviter les erreurs de sécurité.

Plugin jQuery:

 jQuery.fn.selText = function() { var obj = this[0]; if ($.browser.msie) { var range = obj.offsetParent.createTextRange(); range.moveToElementText(obj); range.select(); } else if ($.browser.mozilla || $.browser.opera) { var selection = obj.ownerDocument.defaultView.getSelection(); var range = obj.ownerDocument.createRange(); range.selectNodeContents(obj); selection.removeAllRanges(); selection.addRange(range); } else if ($.browser.safari) { var selection = obj.ownerDocument.defaultView.getSelection(); selection.setBaseAndExtent(obj, 0, obj, 1); } return this; } 

Je l'ai testé dans IE8, Firefox, Opera, Safari, Chrome (versions actuelles). Je ne suis pas sûr que cela fonctionne dans les anciennes versions d'IE (sincèrement, je m'en fous).

Ce fil contient des choses vraiment merveilleuses. Mais je ne peux pas le faire directement sur cette page en utilisant FF 3.5b99 + FireBug en raison d’une “erreur de sécurité”.

Yipee !! J’ai pu sélectionner une barre latérale droite complète avec ce code en espérant que cela vous aidera:

  var r = document.createRange(); var w=document.getElementById("sidebar"); r.selectNodeContents(w); var sel=window.getSelection(); sel.removeAllRanges(); sel.addRange(r); 

PS: – Je n’ai pas pu utiliser les objects renvoyés par les sélecteurs jquery comme

  var w=$("div.welovestackoverflow",$("div.sidebar")); //this throws **security exception** r.selectNodeContents(w); 

Je cherchais la même chose, ma solution était la suivante:

 $('#el-id').focus().select(); 

J’ai aimé la réponse de lepe à quelques exceptions près:

  1. Renifleur de navigateur, jQuery ou no n’est pas optimal
  2. SEC
  3. Ne fonctionne pas dans IE8 si le parent de obj ne supporte pas createTextRange
  4. La capacité de Chrome à utiliser setBaseAndExtent doit être exploitée (IMO)
  5. Ne sélectionnera pas le texte couvrant plusieurs éléments DOM (éléments de l’élément “selected”). En d’autres termes, si vous appelez selText sur un div contenant plusieurs éléments span, il ne sélectionnera pas le texte de chacun de ces éléments. C’était un casse-tête pour moi, YMMV.

Voici ce que j’ai trouvé, avec un clin d’œil à la réponse de lepe pour l’inspiration. Je suis sûr que je serai ridiculisé car c’est peut-être un peu lourd (et pourrait même être plus difficile mais je digresse). Mais cela fonctionne et évite le reniflage par navigateur et c’est le point .

 selectText:function(){ var range, selection, obj = this[0], type = { func:'function', obj:'object' }, // Convenience is = function(type, o){ return typeof o === type; }; if(is(type.obj, obj.ownerDocument) && is(type.obj, obj.ownerDocument.defaultView) && is(type.func, obj.ownerDocument.defaultView.getSelection)){ selection = obj.ownerDocument.defaultView.getSelection(); if(is(type.func, selection.setBaseAndExtent)){ // Chrome, Safari - nice and easy selection.setBaseAndExtent(obj, 0, obj, $(obj).contents().size()); } else if(is(type.func, obj.ownerDocument.createRange)){ range = obj.ownerDocument.createRange(); if(is(type.func, range.selectNodeContents) && is(type.func, selection.removeAllRanges) && is(type.func, selection.addRange)){ // Mozilla range.selectNodeContents(obj); selection.removeAllRanges(); selection.addRange(range); } } } else if(is(type.obj, document.body) && is(type.obj, document.body.createTextRange)) { range = document.body.createTextRange(); if(is(type.obj, range.moveToElementText) && is(type.obj, range.select)){ // IE most likely range.moveToElementText(obj); range.select(); } } // Chainable return this; } 

C’est tout. Une partie de ce que vous voyez est la lisibilité et / ou la commodité. Testé sur Mac dans les dernières versions d’Opera, Safari, Chrome, Firefox et IE. Également testé dans IE8. Aussi, je ne déclare généralement que les variables si / quand cela est nécessaire à l’intérieur des blocs de code, mais jslint suggère qu’elles soient toutes déclarées en haut. Ok jslint.

Modifier J’ai oublié d’inclure comment lier ceci au code de l’op:

 function SelectText(element) { $("#" + element).selectText(); } 

À votre santé

Une version mise à jour qui fonctionne en chrome:

 function SelectText(element) { var doc = document; var text = doc.getElementById(element); if (doc.body.createTextRange) { // ms var range = doc.body.createTextRange(); range.moveToElementText(text); range.select(); } else if (window.getSelection) { var selection = window.getSelection(); var range = doc.createRange(); range.selectNodeContents(text); selection.removeAllRanges(); selection.addRange(range); } } $(function() { $('p').click(function() { SelectText("selectme"); }); }); 

http://jsfiddle.net/KcX6A/326/

lepe – Cela fonctionne très bien pour moi merci! Je mets votre code dans un fichier plug-in, puis je l’ai utilisé conjointement avec chaque instruction afin que vous puissiez avoir plusieurs balises pre et plusieurs liens “Select all” sur une seule page et il sélectionne le pré correct pour mettre en évidence:

   

Vous pouvez utiliser la fonction suivante pour sélectionner le contenu de n’importe quel élément:

 jQuery.fn.selectText = function(){ this.find('input').each(function() { if($(this).prev().length == 0 || !$(this).prev().hasClass('p_copy')) { $('

').insertBefore($(this)); } $(this).prev().html($(this).val()); }); var doc = document; var element = this[0]; console.log(this, element); if (doc.body.createTextRange) { var range = document.body.createTextRange(); range.moveToElementText(element); range.select(); } else if (window.getSelection) { var selection = window.getSelection(); var range = document.createRange(); range.selectNodeContents(element); selection.removeAllRanges(); selection.addRange(range); } };

Cette fonction peut être appelée comme suit:

 $('#selectme').selectText(); 

Pour toute balise, vous pouvez sélectionner tout le texte à l’intérieur de cette balise par ce code court et simple. Il mettra en surbrillance toute la zone de tag avec une couleur jaune et sélectionnera le texte en un seul clic.

 document.onclick = function(event) { var range, selection; event.target.style.backgroundColor = 'yellow'; selection = window.getSelection(); range = document.createRange(); range.selectNodeContents(event.target); selection.removeAllRanges(); selection.addRange(range); }; 

Jetez un coup d’œil à l’ object Selection (moteur Gecko) et à l’ object TextRange (moteur Trident). Je ne connais pas de framework JavaScript prenant en charge tous les navigateurs, mais je ne l’ai jamais cherché non plus, il est possible que même jQuery l’a.

La méthode de Tim fonctionne parfaitement pour mon cas: sélectionner le texte dans un div pour IE et FF après avoir remplacé la déclaration suivante:

 range.moveToElementText(text); 

avec ce qui suit:

 range.moveToElementText(el); 

Le texte dans le div est sélectionné en cliquant dessus avec la fonction jQuery suivante:

 $(function () { $("#divFoo").click(function () { selectElementText(document.getElementById("divFoo")); }) }); 

Voici une autre solution simple pour obtenir le texte sélectionné sous forme de chaîne, vous pouvez facilement utiliser cette chaîne pour append un élément div enfant dans votre code:

 var text = ''; if (window.getSelection) { text = window.getSelection(); } else if (document.getSelection) { text = document.getSelection(); } else if (document.selection) { text = document.selection.createRange().text; } text = text.toSsortingng(); 

jQuery.browser.webkit ajouté à “else if” pour Chrome. Impossible de le faire fonctionner dans Chrome 23.

Faites ce script ci-dessous pour sélectionner le contenu dans une


qui a la class="code" .

 jQuery( document ).ready(function() { jQuery('pre.code').attr('title', 'Click to select all'); jQuery( '#divFoo' ).click( function() { var refNode = jQuery( this )[0]; if ( jQuery.browser.msie ) { var range = document.body.createTextRange(); range.moveToElementText( refNode ); range.select(); } else if ( jQuery.browser.mozilla || jQuery.browser.opera || jQuery.browser.webkit ) { var selection = refNode.ownerDocument.defaultView.getSelection(); console.log(selection); var range = refNode.ownerDocument.createRange(); range.selectNodeContents( refNode ); selection.removeAllRanges(); selection.addRange( range ); } else if ( jQuery.browser.safari ) { var selection = refNode.ownerDocument.defaultView.getSelection(); selection.setBaseAndExtent( refNode, 0, refNode, 1 ); } } ); } ); 

Selon la documentation de jQuery de select() :

Déclenche l’événement select de chaque élément correspondant. Cela entraîne l’exécution de toutes les fonctions liées à cet événement select et appelle l’action select par défaut du navigateur sur les éléments correspondants.

Vous expliquez pourquoi jQuery select() ne fonctionnera pas dans ce cas.

Mon cas particulier d’utilisation consistait à sélectionner une plage de texte à l’intérieur d’un élément span modifiable, qui, pour autant que je sache, n’est décrit dans aucune des réponses.

La principale différence est que vous devez passer un noeud de type Text à l’object Range , comme décrit dans la documentation de Range.setStart () :

Si le startNode est un noeud de type Text, Comment ou CDATASection , alors startOffset correspond au nombre de caractères depuis le début de startNode. Pour les autres types de nœuds, startOffset correspond au nombre de nœuds enfants entre le début du nœud de démarrage.

Le nœud Text est le premier nœud enfant d’un élément span. Pour l’obtenir, accédez à childNodes[0] de l’élément span. Le rest est le même que dans la plupart des autres réponses.

Voici un exemple de code:

 var startIndex = 1; var endIndex = 5; var element = document.getElementById("spanId"); var textNode = element.childNodes[0]; var range = document.createRange(); range.setStart(textNode, startIndex); range.setEnd(textNode, endIndex); var selection = window.getSelection(); selection.removeAllRanges(); selection.addRange(range); 

Autre documentation pertinente:
Gamme
Sélection
Document.createRange ()
Window.getSelection ()