Par programmation sélectionner du texte dans un contenteditable élément HTML?
en JavaScript, il est possible de sélectionner programmatiquement un texte dans un élément input
ou textarea
. Vous pouvez focaliser une entrée avec ipt.focus()
, puis sélectionner son contenu avec ipt.select()
. Vous pouvez même sélectionner une gamme spécifique avec ipt.setSelectionRange(from,to)
.
ma question Est: y a-t-il un moyen de le faire dans un élément contenteditable
aussi?
j'ai trouvé que je peux faire elem.focus()
, pour mettre le caret dans un élément contenteditable
, mais ensuite lancer elem.select()
ne fonctionne pas (et ne fonctionne pas non plus setSelectionRange
). Je ne trouve rien sur le web à ce sujet, mais peut-être que je cherche la mauvaise chose...
soit dit en passant, si cela fait une différence, je n'en ai besoin que pour travailler dans Google Chrome, car c'est pour une extension Chrome.
6 réponses
Si vous souhaitez sélectionner tout le contenu d'un élément (contenteditable ou pas) dans Chrome, voici comment. Cela fonctionnera également dans Firefox, Safari 3+, Opera 9+ (peut-être des versions plus anciennes aussi) et IE 9. Vous pouvez également créer des sélections jusqu'au niveau du caractère. Les API dont vous avez besoin sont DOM gamme (Spec actuel est DOM Niveau 2 , voir aussi MDN ) et la sélection , qui est spécifiée dans le cadre d'un new Range spec ( MDN docs ).
function selectElementContents(el) {
var range = document.createRange();
range.selectNodeContents(el);
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
}
var el = document.getElementById("foo");
selectElementContents(el);
en plus de Tim Downs réponse , j'ai fait une solution qui fonctionne même en oldIE:
var selectText = function() {
var range, selection;
if (document.body.createTextRange) {
range = document.body.createTextRange();
range.moveToElementText(this);
range.select();
} else if (window.getSelection) {
selection = window.getSelection();
range = document.createRange();
range.selectNodeContents(this);
selection.removeAllRanges();
selection.addRange(range);
}
};
document.getElementById('foo').ondblclick = selectText;
testé dans IE 8+, Firefox 3+, Opera 9+, & Chrome 2+. Même moi je l'ai mis en place dans un plugin jQuery:
jQuery.fn.selectText = function() {
var range, selection;
return this.each(function() {
if (document.body.createTextRange) {
range = document.body.createTextRange();
range.moveToElementText(this);
range.select();
} else if (window.getSelection) {
selection = window.getSelection();
range = document.createRange();
range.selectNodeContents(this);
selection.removeAllRanges();
selection.addRange(range);
}
});
};
$('#foo').on('dblclick', function() {
$(this).selectText();
});
...et qui est intéressé, voici la même chose pour tous les accros du café:
jQuery.fn.selectText = ->
@each ->
if document.body.createTextRange
range = document.body.createTextRange()
range.moveToElementText @
range.select()
else if window.getSelection
selection = window.getSelection()
range = document.createRange()
range.selectNodeContents @
selection.removeAllRanges()
selection.addRange range
return
mise à jour:
si vous voulez sélectionner le page entière ou contenu d'une région modifiable (marqué avec contentEditable
), vous pouvez le faire beaucoup plus simple en passant à designMode
et en utilisant document.execCommand
:
Il y a un bon point de départ au MDN et un littledocumentation .
var selectText = function () {
document.execCommand('selectAll', false, null);
};
(fonctionne bien dans IE6+, Opera 9+, Firefoy 3+, Chrome 2+) http://caniuse.com/#search=execCommand
Rangy vous permet de faire ce cross-browser avec le même code. Rangy est une implémentation cross-browser des méthodes DOM pour les sélections. Il est bien testé et rend cela beaucoup moins douloureux. Je refuse de toucher contenteditable sans elle.
vous pouvez trouver rangy ici:
http://code.google.com/p/rangy /
avec rangy dans votre projet, vous pouvez toujours écrire ceci, même si le navigateur est IE 8 ou plus tôt et a une API native complètement différente pour les sélections:
var range = rangy.createRange();
range.selectNodeContents(contentEditableNode);
var sel = rangy.getSelection();
sel.removeAllRanges();
sel.addRange(range);
où "contentEditableNode" est le noeud DOM qui possède l'attribut contenteditable. Vous pourriez le rapporter comme ceci:
var contentEditable = document.getElementById('my-editable-thing');
ou si jQuery fait déjà partie de votre projet et que vous le trouvez pratique:
var contentEditable = $('.some-selector')[0];
puisque toutes les réponses existantes traitent des éléments div
, je vais vous expliquer comment le faire avec span
S.
il y a une différence subtile lors de la sélection d'une plage de texte dans un span
. Pour pouvoir passer l'index de début et de fin de texte, vous devez utiliser un noeud Text
, comme décrit ici :
si le startNode est un noeud de type Text, Comment ou CDATASection, puis startOffset est le nombre de caractères à partir du début de startNode. Pour les autres types de noeuds, startOffset est le nombre d'enfants noeuds entre le début du startNode.
var e = document.getElementById("id of the span element you want to select text in");
var textNode = e.childNodes[0]; //text node is the first child node of a span
var r = document.createRange();
var startIndex = 0;
var endIndex = textNode.textContent.length;
r.setStart(textNode, startIndex);
r.setEnd(textNode, endIndex);
var s = window.getSelection();
s.removeAllRanges();
s.addRange(r);
[mise à jour pour corriger l'erreur]
voici un exemple adapté de cette réponse qui semble bien fonctionner dans Chrome - Select range in contenteditable div
var elm = document.getElementById("myText"),
fc = elm.firstChild,
ec = elm.lastChild,
range = document.createRange(),
sel;
elm.focus();
range.setStart(fc,1);
range.setEnd(ec,3);
sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
HTML is:
<div id="myText" contenteditable>test</div>
contenteditable
est juste un attribut, qui est interprété par navigateur. Vous pouvez modifier ces éléments avec des fonctions DOM ordinaires.
voir TextRanges javascript .
Btw, recherche rapide dans l'affirmative, m'a donné quelques résultats .