Comment définir la position du curseur dans l'élément contenteditable (div)?
J'ai ce HTML simple comme exemple:
<div id="editable" contenteditable="true">
text text text<br>
text text text<br>
text text text<br>
</div>
<button id="button">focus</button>
Je veux une chose simple-quand je clique sur le bouton, je veux placer le curseur (curseur) dans un endroit spécifique dans le div modifiable. De la recherche sur le web, j'ai ce JS attaché au clic de bouton, mais cela ne fonctionne pas (FF, Chrome):
var range = document.createRange();
var myDiv = document.getElementById("editable");
range.setStart(myDiv, 5);
range.setEnd(myDiv, 5);
Est - il possible de définir manuellement la position du curseur comme ceci ?
5 réponses
Dans la plupart des navigateurs, vous avez besoin de la Range
et Selection
objets. Vous spécifiez chacune des limites de sélection en tant que nœud et un décalage dans ce nœud. Par exemple, pour définir le curseur sur le cinquième caractère de la deuxième ligne de texte, procédez comme suit:
var el = document.getElementById("editable");
var range = document.createRange();
var sel = window.getSelection();
range.setStart(el.childNodes[2], 5);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
IE
Jsfiddle exemple: http://jsfiddle.net/timdown/vXnCM/
La plupart des réponses que vous trouvez sur le positionnement du curseur contenteditable sont assez simplistes en ce sens qu'elles ne répondent qu'aux entrées avec du texte vanillé. Une fois que vous utilisez des éléments html dans le conteneur, le texte entré est divisé en nœuds et distribué généreusement dans une arborescence.
Pour définir la position du curseur, j'ai cette fonction qui boucle tous les nœuds de texte enfant dans le nœud fourni et définit une plage du début du nœud initial aux caractères .Compter caractère:
function createRange(node, chars, range) {
if (!range) {
range = document.createRange()
range.selectNode(node);
range.setStart(node, 0);
}
if (chars.count === 0) {
range.setEnd(node, chars.count);
} else if (node && chars.count >0) {
if (node.nodeType === Node.TEXT_NODE) {
if (node.textContent.length < chars.count) {
chars.count -= node.textContent.length;
} else {
range.setEnd(node, chars.count);
chars.count = 0;
}
} else {
for (var lp = 0; lp < node.childNodes.length; lp++) {
range = createRange(node.childNodes[lp], chars, range);
if (chars.count === 0) {
break;
}
}
}
}
return range;
};
J'appelle alors la routine avec cette fonction:
function setCurrentCursorPosition(chars) {
if (chars >= 0) {
var selection = window.getSelection();
range = createRange(document.getElementById("test").parentNode, { count: chars });
if (range) {
range.collapse(false);
selection.removeAllRanges();
selection.addRange(range);
}
}
};
La plage.effondrement(faux) place le curseur à la fin de la plage. Je l'ai testé avec les dernières versions de Chrome, IE, Mozilla et Opera et ils fonctionnent tous très bien.
PS. Si quelqu'un est intéressé, j'obtiens la position actuelle du curseur en utilisant ce code:
function isChildOf(node, parentId) {
while (node !== null) {
if (node.id === parentId) {
return true;
}
node = node.parentNode;
}
return false;
};
function getCurrentCursorPosition(parentId) {
var selection = window.getSelection(),
charCount = -1,
node;
if (selection.focusNode) {
if (isChildOf(selection.focusNode, parentId)) {
node = selection.focusNode;
charCount = selection.focusOffset;
while (node) {
if (node.id === parentId) {
break;
}
if (node.previousSibling) {
node = node.previousSibling;
charCount += node.textContent.length;
} else {
node = node.parentNode;
if (node === null) {
break
}
}
}
}
}
return charCount;
};
Le code fait le contraire de la fonction set - il obtient la fenêtre actuelle.getSelection ().focusNode et focusOffset et comptes en arrière tous les caractères de texte rencontrés jusqu'à ce qu'il frappe un nœud parent avec l'id de containerId. La fonction isChildOf vérifie juste avant d'exécuter que le nœud fourni est en fait un enfant du ParentID fourni.
Le code devrait fonctionner directement sans changement, mais je viens de le prendre à partir d'un plugin jQuery que j'ai développé, donc j'ai piraté quelques c'est - Faites-moi savoir si quelque chose ne fonctionne pas!
Il est très difficile de placer le curseur dans la bonne position lorsque vous avez un élément advance comme (p) (span) etc.Le but est d'obtenir (texte de l'objet):
<div id="editable" contenteditable="true">dddddddddddddddddddddddddddd<p>dd</p>psss<p>dd</p><p>dd</p>
<p>text text text</p>
</div>
<p id='we'></p>
<button onclick="set_mouse()">focus</button>
<script>
function set_mouse() {
var as = document.getElementById("editable");
el=as.childNodes[1].childNodes[0];//goal is to get ('we') id to write (object Text) because it work only in object text
var range = document.createRange();
var sel = window.getSelection();
range.setStart(el, 1);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
document.getElementById("we").innerHTML=el;// see out put of we id
}
</script>
Si vous ne souhaitez pas utiliser jQuery, vous pouvez essayer cette approche:
public setCaretPosition() {
const editableDiv = document.getElementById('contenteditablediv');
const lastLine = this.input.nativeElement.innerHTML.replace(/.*?(<br>)/g, '');
const selection = window.getSelection();
selection.collapse(editableDiv.childNodes[editableDiv.childNodes.length - 1], lastLine.length);
}
editableDiv
vous élément modifiable, n'oubliez pas de définir un id
pour cela. Ensuite, vous devez obtenir votre innerHTML
de l'élément et couper toutes les lignes de frein. Et il suffit de définir l'effondrement avec les arguments suivants.
J'écris un surligneur de syntaxe (et un éditeur de code de base), et j'avais besoin de savoir comment taper automatiquement un seul caractère de citation et déplacer le curseur (comme beaucoup d'éditeurs de code de nos jours).
Voici un extrait de ma solution, grâce à beaucoup d'aide de ce fil, les documents MDN, et beaucoup de console MOZ regarder..
//onKeyPress event
if (evt.key === "\"") {
let sel = window.getSelection();
let offset = sel.focusOffset;
let focus = sel.focusNode;
focus.textContent += "\""; //setting div's innerText directly creates new
//nodes, which invalidate our selections, so we modify the focusNode directly
let range = document.createRange();
range.selectNode(focus);
range.setStart(focus, offset);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
}
//end onKeyPress event
Ceci est dans un élément div contenteditable
Je laisse ceci ici en remerciement, réalisant qu'il y a déjà une réponse acceptée.