Dans ce chapitre, nous aborderons la sélection dans le document, ainsi que la sélection dans les champs de formulaire, tels que <input>.
JavaScript peut accéder à une sélection existante, sélectionner/désélectionner des nÅuds du DOM dans leur ensemble ou partiellement, supprimer le contenu sélectionné du document, lâenvelopper dans une balise, etc.
Vous pouvez trouver quelques recettes de tâches courantes à la fin du chapitre, dans la section âRésuméâ. Peut-être que cela couvre vos besoins actuels, mais vous obtiendrez beaucoup plus si vous lisez le texte en entier.
Les objets Range et Selection sont faciles à comprendre, et vous nâaurez besoin dâaucune recette pour les faire faire ce que vous voulez.
Range
Le concept de base de la sélection est la plage (Range), qui est essentiellement une paire de âpoints limitesâ: le début et la fin de la plage.
Un objet Range est créé sans paramètres :
let range = new Range();
Ensuite, nous pouvons définir les limites de la sélection en utilisant range.setStart(node, offset) et range.setEnd(node, offset).
Comme vous pouvez le deviner, nous allons utiliser les objets Range pour la sélection, mais créons dâabord quelques-uns de ces objets.
Sélection partielle du texte
La chose intéressante est que le premier argument node dans les deux méthodes peut être soit un noeud de texte ou un noeud dâélément, et la signification du deuxième argument dépend de cela.
Si node est un noeud de texte, alors offset doit être la position dans son texte.
Par exemple, étant donné lâélément <p>Hello</p>, nous pouvons créer la plage contenant les lettres âllâ comme suit :
<p id="p">Hello</p>
<script>
let range = new Range();
range.setStart(p.firstChild, 2);
range.setEnd(p.firstChild, 4);
// toString d'une plage renvoie son contenu sous forme de texte
console.log(range); // ll
</script>
Ici, nous prenons le premier enfant de <p> (câest le noeud texte) et nous spécifions les positions du texte à lâintérieur de celui-ci :
Sélection des noeuds dâéléments
Alternativement, si node est un noeud dâélément, alors offset doit être le numéro de lâenfant.
Câest pratique pour faire des plages qui contiennent les noeuds dans leur ensemble, et non pas sâarrêter quelque part dans leur texte.
Par exemple, nous avons un fragment de document plus complexe :
<p id="p">Example: <i>italic</i> and <b>bold</b></p>
Voici sa structure DOM avec les nÅuds dâélément et de texte :
Créons une plage pour "Example: <i>italic</i>".
Comme nous pouvons le voir, cette phrase est composée dâexactement deux enfants de <p>, avec les indices 0 et 1 :
-
Le point de départ a
<p>commenodeparent, et0comme décalage (offset).On peut donc le définir comme
range.setStart(p, 0). -
Le point de fin a aussi
<p>commenodeparent, mais2comme décalage (il spécifie la plage jusquâà , mais sans inclureoffset).On peut donc le définir comme
range.setEnd(p, 2).
Voici la démo. Si vous lâexécutez, vous pouvez voir que le texte est sélectionné :
<p id="p">Example: <i>italic</i> and <b>bold</b></p>
<script>
let range = new Range();
range.setStart(p, 0);
range.setEnd(p, 2);
// toString d'une plage renvoie son contenu sous forme de texte, sans balises
console.log(range); // Example: italic
// appliquer cette plage pour la sélection du document (expliqué plus loin)
document.getSelection().addRange(range);
</script>
Voici un banc dâessai plus flexible dans lequel vous pouvez définir des valeurs de début et de fin de plage et explorer dâautres variantes :
<p id="p">Example: <i>italic</i> and <b>bold</b></p>
From <input id="start" type="number" value=1> â To <input id="end" type="number" value=4>
<button id="button">Click to select</button>
<script>
button.onclick = () => {
let range = new Range();
range.setStart(p, start.value);
range.setEnd(p, end.value);
// appliquer la sélection, expliquée plus loin
document.getSelection().removeAllRanges();
document.getSelection().addRange(range);
};
</script>
E.g. en sélectionnant dans le même <p> de lâoffset 1 à 4 on obtient <i>italic</i> and <b>bold</b>:
Nous ne sommes pas obligés dâutiliser le même noeud dans setStart et setEnd. Une plage peut sâétendre sur de nombreux noeuds non liés. Il est seulement important que la fin soit après le début dans le document.
Sélection dâun plus grand fragment
Faisons une sélection plus grande dans notre exemple, comme ceci :
Nous savons déjà comment faire. Nous devons juste définir le début et la fin comme un offset relatif dans les nÅuds de texte.
Nous devons créer une plage, qui :
- commence à la position 2 dans
<p>firstChild (en prenant toutes les lettres sauf les deux premières de "Example: "). - se termine à la position 3 dans
<b>firstChild (en prenant les trois premières lettres de âboldâ, mais pas plus) :
<p id="p">Example: <i>italic</i> and <b>bold</b></p>
<script>
let range = new Range();
range.setStart(p.firstChild, 2);
range.setEnd(p.querySelector('b').firstChild, 3);
console.log(range); // ample: italic and bol
// utiliser cette plage pour la sélection (expliqué plus loin)
window.getSelection().addRange(range);
</script>
Comme vous pouvez le voir, il est assez facile de créer une plage de ce que lâon veut.
Si nous voulons prendre les noeuds dans leur ensemble, nous pouvons passer des éléments dans setStart/setEnd. Sinon, nous pouvons travailler au niveau du texte.
Propriétés de la plage
Lâobjet range que nous avons créé dans lâexemple ci-dessus a les propriétés suivantes :
startContainer,startOffsetâ nÅud et offset du début,- dans lâexemple ci-dessus : premier noeud de texte à lâintérieur de
<p>et2.
- dans lâexemple ci-dessus : premier noeud de texte à lâintérieur de
endContainer,endOffsetâ noeud et offset de la fin,- dans lâexemple ci-dessus : premier noeud de texte dans
<b>et3.
- dans lâexemple ci-dessus : premier noeud de texte dans
collapsedâ booléen,truesi la plage commence et se termine sur le même point (donc il nây a pas de contenu à lâintérieur de la plage),- dans lâexemple ci-dessus :
false.
- dans lâexemple ci-dessus :
commonAncestorContainerâ lâancêtre commun le plus proche de tous les noeuds de la plage,- dans lâexemple ci-dessus :
<p>.
- dans lâexemple ci-dessus :
Méthodes de sélection de plages
Il existe de nombreuses méthodes pratiques pour manipuler les plages.
Nous avons déjà vu setStart et setEnd, voici dâautres méthodes similaires.
Définir le début de la plage :
setStart(node, offset)définit le début à : positionoffsetdansnode.setStartBefore(node)définit le début à : juste avantnode.setStartAfter(node)définit le début à : juste aprèsnode.
Définir la fin de la plage (méthodes similaires) :
setEnd(node, offset)définit la fin à : positionoffsetdansnode.setEndBefore(node)définit la fin à : juste avantnode.setEndAfter(node)définit la fin à : juste aprèsnode.
Techniquement, setStart/setEnd peuvent faire nâimporte quoi, mais plus de méthodes fournissent plus de commodité.
Dans toutes ces méthodes, node peut être un noeud de texte ou dâélément : pour les noeuds de texte, offset saute autant de caractères, tandis que pour les noeuds dâéléments, autant de noeuds enfants.
Encore plus de méthodes pour créer des plages :
selectNode(node)définit la plage pour sélectionner lenodeentier.selectNodeContents(node)sélectionne le contenu dunodedans son intégralité.collapse(toStart)sitoStart=true, définissez end=start, sinon définissez start=end, ce qui réduit la plage de sélection.cloneRange()crée une nouvelle plage avec le même début et la même fin.
Méthodes dâédition des plages
Une fois que la plage est créée, nous pouvons manipuler son contenu en utilisant ces méthodes :
deleteContents()â supprime le contenu de la plage du document.extractContents()â supprime le contenu de la plage du document et le retourne en tant que DocumentFragment.cloneContents()â clone le contenu dâune plage et le renvoie en tant que DocumentFragment.insertNode(node)â Insèrenodedans le document au début de la plage.surroundContents(node)â entourenodedu contenu de la plage. Pour que cela fonctionne, la plage doit contenir à la fois des balises dâouverture et de fermeture pour tous les éléments quâelle contient : pas de plages partielles comme<i>abc.
Avec ces méthodes, nous pouvons faire pratiquement nâimporte quoi avec les noeuds sélectionnés.
Voici le banc dâessai pour les voir en action :
Cliquez sur les boutons pour exécuter des méthodes sur la sélection, "resetExample" pour la réinitialiser.
<p id="p">Example: <i>italic</i> and <b>bold</b></p>
<p id="result"></p>
<script>
let range = new Range();
// Chaque méthode démontrée est représentée ici :
let methods = {
deleteContents() {
range.deleteContents()
},
extractContents() {
let content = range.extractContents();
result.innerHTML = "";
result.append("extracted: ", content);
},
cloneContents() {
let content = range.cloneContents();
result.innerHTML = "";
result.append("cloned: ", content);
},
insertNode() {
let newNode = document.createElement('u');
newNode.innerHTML = "NEW NODE";
range.insertNode(newNode);
},
surroundContents() {
let newNode = document.createElement('u');
try {
range.surroundContents(newNode);
} catch(e) { console.log(e) }
},
resetExample() {
p.innerHTML = `Example: <i>italic</i> and <b>bold</b>`;
result.innerHTML = "";
range.setStart(p.firstChild, 2);
range.setEnd(p.querySelector('b').firstChild, 3);
window.getSelection().removeAllRanges();
window.getSelection().addRange(range);
}
};
for(let method in methods) {
document.write(`<div><button onclick="methods.${method}()">${method}</button></div>`);
}
methods.resetExample();
</script>
Il existe également des méthodes permettant de comparer des plages, mais elles sont rarement utilisées. Si vous en avez besoin, veuillez vous reporter à la spec ou au manuel MDN.
Sélection
Range est un objet générique pour gérer les plages de sélection. Bien que la création dâune Range ne signifie pas que nous voyons une sélection à lâécran.
Nous pouvons créer des objets Range, les faire circuler â ils ne sélectionnent rien visuellement par eux-mêmes.
La sélection du document est représentée par un objet Selection, qui peut être obtenu par window.getSelection() ou document.getSelection(). Une sélection peut inclure zéro ou plusieurs plages. Câest du moins ce que dit la spécification de Selection API. En pratique cependant, seul Firefox permet de sélectionner plusieurs plages dans le document en utilisant Ctrl+click (Cmd+click pour Mac).
Voici une capture dâécran dâune sélection avec 3 plages, réalisée dans Firefox :
Les autres navigateurs prennent en charge au maximum 1 plage. Comme nous allons le voir, certaines méthodes de Selection impliquent quâil peut y avoir plusieurs plages, mais là encore, dans tous les navigateurs sauf Firefox, il y a au maximum 1 plage.
Voici une petite démo qui montre la sélection actuelle (sélectionner quelque chose et cliquer) sous forme de texte :
Propriétés de Selection
Comme nous lâavons dit, une sélection peut en théorie contenir plusieurs plages. Nous pouvons obtenir ces objets range en utilisant la méthode :
getRangeAt(i)â obtient la i-ième plage, en commençant par0. Dans tous les navigateurs sauf Firefox, seul0est utilisé.
Il existe également des propriétés qui sont souvent plus pratiques.
Comme pour une plage, un objet selection a un début, appelé âanchorâ, et une fin, appelée âfocusâ.
Les principales propriétés de selection sont :
anchorNodeâ le noeud où la sélection commence.anchorOffsetâ le décalage (offset) dansanchorNodeoù la sélection commence.focusNodeâ le noeud où la sélection se termine.focusOffsetâ le décalage dansfocusNodeoù la sélection se termine.isCollapsedâtruesi la sélection ne sélectionne rien (plage vide), ou si elle nâexiste pas.rangeCountâ nombre de plages dans la sélection, maximum1dans tous les navigateurs sauf Firefox.
Il y a une différence importante entre anchor/focus dâune sélection et start/end dâun objet Range.
Comme nous le savons, les objets Range ont toujours leur début avant leur fin.
Pour les sélections, ce nâest pas toujours le cas.
La sélection dâun objet avec une souris peut se faire dans les deux sens : de gauche à droite ou de droite à gauche.
En dâautres termes, lorsque le bouton de la souris est enfoncé, puis quâil avance dans le document, sa fin (focus) se trouvera après son début (anchor).
E.g. si lâutilisateur commence à sélectionner avec la souris et passe de âExampleâ à âitalicâ :
â¦Mais la même sélection pourrait être faite en sens inverse : en partant de âitalicâ vers âExampleâ (sens inverse), alors sa fin (focus) sera avant le début (anchor) :
Ãvénements de sélection
Il y a des événements pour suivre la trace de la sélection :
elem.onselectstartâ quand une sélection débute spécifiquement sur lâélémentelem(ou à lâintérieur de celui-ci). Par exemple, lorsque lâutilisateur appuie sur le bouton de la souris sur cet élément et commence à déplacer le pointeur.- En empêchant lâaction par défaut, on annule le démarrage de la sélection. Le démarrage dâune sélection à partir de cet élément devient donc impossible, mais lâélément reste tout de même sélectionnable. Le visiteur doit simplement démarrer la sélection à partir dâun autre endroit.
document.onselectionchangeâ quand une sélection change ou commence.- Attention : ce gestionnaire ne peut être défini que sur
document, il suit toutes les sélections quâil contient.
- Attention : ce gestionnaire ne peut être défini que sur
Démonstration du suivi des sélections
Voici une petite démo. Elle suit la sélection courante sur le document et montre ses limites :
<p id="p">Select me: <i>italic</i> and <b>bold</b></p>
From <input id="from" disabled> â To <input id="to" disabled>
<script>
document.onselectionchange = function() {
let selection = document.getSelection();
let {anchorNode, anchorOffset, focusNode, focusOffset} = selection;
// anchorNode et focusNode sont des nÅuds de texte habituellement
from.value = `${anchorNode?.data}, offset ${anchorOffset}`;
to.value = `${focusNode?.data}, offset ${focusOffset}`;
};
</script>
Démonstration de la copie dâune sélection
Il existe deux approches pour copier le contenu sélectionné :
- Nous pouvons utiliser
document.getSelection().toString()pour le récupérer sous forme de texte. - Sinon, pour copier le DOM complet, par exemple si nous devons garder le formatage, nous pouvons obtenir les plages sous-jacentes avec
getRangesAt(...). Un objetRange, à son tour, a la méthodecloneContents()qui clone son contenu et retourne un objetDocumentFragment, que nous pouvons insérer ailleurs.
Voici la démonstration de la copie du contenu sélectionné à la fois comme texte et comme noeuds DOM :
<p id="p">Select me: <i>italic</i> and <b>bold</b></p>
Cloned: <span id="cloned"></span>
<br>
As text: <span id="astext"></span>
<script>
document.onselectionchange = function() {
let selection = document.getSelection();
cloned.innerHTML = astext.innerHTML = "";
// Cloner les noeuds du DOM Ã partir de plages (nous supportons le multiselect ici)
for (let i = 0; i < selection.rangeCount; i++) {
cloned.append(selection.getRangeAt(i).cloneContents());
}
// Obtenir sous forme de texte
astext.innerHTML += selection;
};
</script>
Méthodes de sélection
Nous pouvons travailler avec la sélection en ajoutant/supprimant (add/remove) des plages :
getRangeAt(i)â obtient la i-ième plage, en commençant par0. Dans tous les navigateurs sauf Firefox, seul0est utilisé.addRange(range)â ajouterangeà la sélection. Tous les navigateurs, à lâexception de Firefox, ignorent lâappel, si la sélection a déjà une plage associée.removeRange(range)â supprimerangede la sélection.removeAllRanges()â supprime toutes les plages.empty()â alias deremoveAllRanges.
Il y a aussi des méthodes pratiques pour manipuler directement la plage de sélection, sans appels intermédiaires à Range :
collapse(node, offset)â remplace la plage sélectionnée par une nouvelle qui commence et se termine aunodedonné, à la positionoffset.setPosition(node, offset)â alias decollapse.collapseToStart()â réduit (remplace par une plage vide) au début de la sélection.collapseToEnd()â réduit à la fin de la sélection.extend(node, offset)â déplace le focus de la sélection vers lenodeet la positionoffsetdonnés.setBaseAndExtent(anchorNode, anchorOffset, focusNode, focusOffset)â remplace la plage de sélection avec les valeurs de débutanchorNode/anchorOffsetet de finfocusNode/focusOffset. Tout le contenu situé entre les deux est sélectionné.selectAllChildren(node)â sélectionne tous les enfants dunode.deleteFromDocument()â supprime le contenu sélectionné du document.containsNode(node, allowPartialContainment = false)â vérifie si la sélection contientnode(partiellement si le second argument esttrue).
Pour la plupart des tâches, ces méthodes sont suffisantes, il nây a pas besoin dâaccéder à lâobjet Range sous-jacent.
Par exemple, sélectionner le contenu entier du paragraphe <p> :
<p id="p">Select me: <i>italic</i> and <b>bold</b></p>
<script>
// sélectionnez du 0-ème enfant de <p> au dernier element fils
document.getSelection().setBaseAndExtent(p, 0, p, p.childNodes.length);
</script>
La même chose en utilisant Range :
<p id="p">Select me: <i>italic</i> and <b>bold</b></p>
<script>
let range = new Range();
range.selectNodeContents(p); // ou selectNode(p) pour sélectionner également la balise <p>
document.getSelection().removeAllRanges(); // effacer la sélection existante s'il y en a une
document.getSelection().addRange(range);
</script>
Si une sélection du document existe déjà , videz-la dâabord avec removeAllRanges(). Puis ajoutez des plages. Sinon, tous les navigateurs, sauf Firefox, ignorent les nouvelles plages.
Lâexception est certaines méthodes de sélection, qui remplacent la sélection existante, comme setBaseAndExtent.
Sélection dans les contrôles de formulaires
Les éléments de formulaire, tels que input et textarea fournissent une API spéciale pour la sélection, sans objets Selection ou Range. Comme une valeur dâentrée est un texte pur, pas du HTML, il nây a pas besoin de tels objets, tout est beaucoup plus simple.
Propriétés :
input.selectionStartâ position du début de la sélection (accessible en écriture).input.selectionEndâ position de la fin de la sélection (accessible en écriture).input.selectionDirectionâ direction de la sélection, une parmi : âforwardâ, âbackwardâ ou ânoneâ (si, par exemple, la sélection est effectuée par un double clic de souris).
les événements :
input.onselectâ se déclenche lorsque quelque chose est sélectionné.
Méthodes :
-
input.select()â sélectionne tout dans le contrôle de texte (peut êtretextareaau lieu deinput). -
input.setSelectionRange(start, end, [direction])â modifie la sélection pour quâelle sâétende de la positionstartÃend, dans la direction donnée (facultatif). -
input.setRangeText(replacement, [start], [end], [selectionMode])â remplace une plage de texte par le nouveau texte.Les arguments facultatifs
startetend, sâils sont fournis, définissent le début et la fin de la plage, sinon la sélection de lâutilisateur est utilisée.Le dernier argument,
selectionMode, détermine comment la sélection sera définie après que le texte ait été remplacé. Les valeurs possibles sont :"select"â le texte nouvellement inséré sera sélectionné."start"â la plage de sélection se réduit juste avant le texte inséré (le curseur sera immédiatement devant)."end"â la plage de sélection se réduit juste après le texte inséré (le curseur sera juste après)."preserve"â tente de préserver la sélection. Câest la valeur par défaut.
Voyons maintenant ces méthodes en action.
Exemple : suivi de sélection
Par exemple, ce code utilise lâévénement onselect pour suivre la sélection :
<textarea id="area" style="width:80%;height:60px">
Selecting in this text updates values below.
</textarea>
<br>
From <input id="from" disabled> â To <input id="to" disabled>
<script>
area.onselect = function() {
from.value = area.selectionStart;
to.value = area.selectionEnd;
};
</script>
Veuillez noter :
onselectse déclenche lorsque quelque chose est sélectionné, mais pas lorsque la sélection est supprimée.- Lâévénement
document.onselectionchangene devrait pas se déclencher pour les sélections à lâintérieur dâun contrôle de formulaire, selon la spec, car il nâest pas lié à la sélection et aux plages dudocument. Certains navigateurs le génèrent, mais il ne faut pas sây fier.
Exemple : déplacement du curseur
Nous pouvons changer selectionStart et selectionEnd, cela définit la sélection.
Un cas particulier important est celui où selectionStart et selectionEnd sont égaux. Dans ce cas, il sâagit exactement de la position du curseur. Ou, pour le dire autrement, lorsque rien nâest sélectionné, la sélection est réduite à la position du curseur.
Donc, en mettant selectionStart et selectionEnd à la même valeur, on déplace le curseur.
Par exemple :
<textarea id="area" style="width:80%;height:60px">
Focus on me, the cursor will be at position 10.
</textarea>
<script>
area.onfocus = () => {
// setTimeout de délai zéro à exécuter après la fin de l'action "focus" du navigateur
setTimeout(() => {
// nous pouvons définir n'importe quelle sélection
// si start=end, le curseur se trouve exactement à cet endroit
area.selectionStart = area.selectionEnd = 10;
});
};
</script>
Exemple : modifier la sélection
Pour modifier le contenu de la sélection, on peut utiliser la méthode input.setRangeText(). Bien sûr, nous pouvons lire selectionStart/End et, avec la connaissance de la sélection, modifier la chaîne partielle (substring) correspondante de value, mais setRangeText est plus puissant et souvent plus pratique.
Câest une méthode plus ou moins complexe. Dans sa forme la plus simple à un argument, elle remplace la plage sélectionnée par lâutilisateur et supprime la sélection.
Par exemple, ici la sélection de lâutilisateur sera entourée de *...* :
<input id="input" style="width:200px" value="Select here and click the button">
<button id="button">Wrap selection in stars *...*</button>
<script>
button.onclick = () => {
if (input.selectionStart == input.selectionEnd) {
return; // rien n'est sélectionné
}
let selected = input.value.slice(input.selectionStart, input.selectionEnd);
input.setRangeText(`*${selected}*`);
};
</script>
Avec plus dâarguments, nous pouvons définir start et end de range.
Dans cet exemple, nous trouvons "THIS" dans le texte de saisie, le remplaçons et gardons le remplacement sélectionné :
<input id="input" style="width:200px" value="Replace THIS in text">
<button id="button">Replace THIS</button>
<script>
button.onclick = () => {
let pos = input.value.indexOf("THIS");
if (pos >= 0) {
input.setRangeText("*THIS*", pos, pos + 4, "select");
input.focus(); // focus pour rendre la sélection visible
}
};
</script>
Exemple : insérer au curseur
Si rien nâest sélectionné, ou si nous utilisons des start et end égaux dans setRangeText, alors le nouveau texte est juste inséré, rien nâest supprimé.
On peut aussi insérer quelque chose âau curseurâ en utilisant setRangeText.
Voici un bouton qui insère "HELLO" à la position du curseur et place le curseur immédiatement après. Si la sélection nâest pas vide, elle est remplacée (nous pouvons le détecter en comparant selectionStart!=selectionEnd et faire autre chose à la place) :
<input id="input" style="width:200px" value="Text Text Text Text Text">
<button id="button">Insert "HELLO" at cursor</button>
<script>
button.onclick = () => {
input.setRangeText("HELLO", input.selectionStart, input.selectionEnd, "end");
input.focus();
};
</script>
Rendre un élément non sélectionnable
Pour rendre quelque chose non sélectionnable, il y a trois approches :
-
Utiliser la propriété CSS
user-select: none.<style> #elem { user-select: none; } </style> <div>Selectable <div id="elem">Unselectable</div> Selectable</div>Cela ne permet pas à la sélection de commencer Ã
elem. Mais lâutilisateur peut commencer la sélection ailleurs et inclureelemdans celle-ci.Dans ce cas,
elemdeviendra une partie dedocument.getSelection(), et la sélection aura bien lieu, mais son contenu sera généralement ignoré dans le copier-coller. -
Empêcher lâaction par défaut dans les événements
onselectstartoumousedown.<div>Selectable <div id="elem">Unselectable</div> Selectable</div> <script> elem.onselectstart = () => false; </script>Cela empêche de commencer la sélection sur
elem, mais le visiteur peut la commencer sur un autre élément, puis lâétendre Ãelem.Câest pratique quand il y a un autre gestionnaire dâévénement sur la même action qui déclenche la sélection (par exemple
mousedown). Nous désactivons donc la sélection pour éviter tout conflit, tout en permettant au contenu deelemdâêtre copié. -
On peut aussi effacer la sélection après le fait avec
document.getSelection().empty(). Câest rarement utilisé, car cela provoque un clignotement indésirable lorsque la sélection apparaît-disparaît.
Quelques références
Résumé
Nous avons couvert deux API différentes pour les sélections :
- Pour le document : objets
SelectionetRange. - Pour
input,textarea: méthodes et propriétés supplémentaires.
La deuxième API est très simple, puisquâelle fonctionne avec du texte.
Les recettes les plus utilisées sont probablement :
- Obtenir la sélection :
let selection = document.getSelection(); let cloned = /* élément pour cloner les nÅuds sélectionnés vers */; // puis appliquer les méthodes Range à selection.getRangeAt(0) // ou, comme ici, à toutes les plages (range) pour supporter la sélection multiple. for (let i = 0; i < selection.rangeCount; i++) { cloned.append(selection.getRangeAt(i).cloneContents()); } - Mise en place de la sélection :
let selection = document.getSelection(); // directement: selection.setBaseAndExtent(...from...to...); // ou nous pouvons créer une plage et : selection.removeAllRanges(); selection.addRange(range);
Et enfin, à propos du curseur. La position du curseur dans les éléments modifiables, comme <textarea> est toujours au début ou à la fin de la sélection. Nous pouvons lâutiliser pour obtenir la position du curseur ou pour le déplacer en définissant elem.selectionStart et elem.selectionEnd.
Commentaires
<code>, pour plusieurs lignes â enveloppez-les avec la balise<pre>, pour plus de 10 lignes - utilisez une sandbox (plnkr, jsbin, codepenâ¦)