JavaScript "contenteditable" - obtention/réglage de la position Caret
j'ai lu quelques billets sur le positionnement du caret, mais aucun ne semble répondre à mon problème particulier.
- j'ai 2 divs ( div1 et div2)
- div1 = div non éditable
- div2 = contenteditable div
- les deux divs contiennent exactement le même contenu
- lorsque l'utilisateur clique sur div1, il obtient caché, et div2 apparaît dans l'emplacement exact et l'utilisateur peut edit
Le problème: je veux que le curseur apparaisse dans l'emplacement exact sur div2 comme div1
donc, j'ai besoin d'un moyen pour lire l'emplacement où l'utilisateur clique sur div1, et puis quand div2 apparaît placer le curseur / caret dans ce même emplacement, donc un getCaretLocation (in_div_id) et setCaretLocation (in_div_id) ensemble de fonctions.
de Toute façon de le faire?
Merci
6 réponses
courte réponse : Vous ne pouvez pas
réponse: le problème que vous rencontrerez est que vous serez en mesure d'obtenir les coordonnées (x,y) pour l'événement de clic sur div1, mais toute implémentation de la position de caret tout en exigeant que vous connaissiez la position du caret dans le contenu (qui est le nombre de caractères précédant le caret).
pour convertir les coordonnées (x, y) en une position de caractère, vous devez savoir combien de caractères il y avait avant. (IE. à gauche sur la ligne en cours et au-dessus, si le texte est ltr).
Si vous utilisez une police à largeur fixe, vous pouvez simplifier le problème : cartographie d'un (x,y) les coordonnées (ligne, colonne) de coordonner sur une grille de caractères.
cependant, vous rencontrez toujours le problème de ne pas savoir comment le texte est enveloppé. Par exemple :
------------------
|Lorem ipsum |
|dolor sit amet |
|consectetur |
|adipiscing elit |
------------------
Si l'utilisateur clique sur le d dolor, vous savez que le personnage est la 1ère à la 2ème ligne, mais sans connaissant l'algorithme d'enrubannage, il n'y a pas moyen que vous sachiez que c'est le 13e personnage de "Lorem ipsum dolor sit...". Et il n'y a aucune garantie qu'un tel algorithme d'enrubannage soit identique à travers les navigateurs et la plate-forme.
maintenant, ce que je me demande c'est pourquoi vous utiliseriez 2 synced différents div
en premier lieu ? Ne serait-il pas plus facile d'utiliser une seule div et de définir son contenu à éditable lorsque l'utilisateur clique (ou survole) ?
vous pouvez insérer un minuscule élément de portée au caret, obtenir sa position, et l'enlever. Pour une bibliothèque de sélection et de portée de navigateur croisées, voir longiligne.
vous pouvez, fondamentalement, vous avez besoin de définir temporaire contenu modifiable sur votre première div pour attraper signe pos
$('div1').hover(function()
{ $(this).attr('contenteditable','true');
},function()
{ $(this).removeAttr('contenteditable');
}).mouseup(function()
{ var t = $(this);
// get caret position and remove content editable
var caret = t.getCaret();
t.removeAttr('contenteditable');
// do your div switch stuff
...
// and apply saved caret position
$('div2').setCaret(caret);
});
maintenant juste besoin de get/set signe méthode :)
modifier > voici mon propre, (démonstration)
getSelection:function($e)
{ if(undefined === window.getSelection) return false;
var range = window.getSelection().getRangeAt(0);
function getTreeOffset($root,$node)
{ if($node.parents($root).length === 0) return false; // is node child of root ?
var tree = [], treesize = 0;
while(1)
{ if($node.is($root)) break;
var index, $parent = $node.parent();
index = $parent.contents().index($node);
if(index !== -1) { tree[treesize++] = index; } $node = $parent;
}; return tree.reverse();
}
var start = getTreeOffset($e,$(range.startContainer));
var end = getTreeOffset($e,$(range.endContainer));
if(start & end === false) return false;
return {start:start,end:end,startOffset:range.startOffset,endOffset:range.endOffset};
}, setSelection:function($e,s,win)
{ $e.focus(); if(s === false) return; var sel = win.getSelection(); sel.removeAllRanges();
function getNode($e,s)
{ var node = $e;
for( var n=0;n<s.length;n++ )
{ var index = s[n]; if(index < 0) break;
node = node.contents(':eq('+index+')');
} return node.get(0);
}
var start = getNode($e,s.start), end = getNode($e,s.end), range = win.document.createRange();
range.setStart(start,s.startOffset); range.setEnd(end,s.endOffset); sel.addRange(range);
}
Lorsque vous cliquez sur un élément, une Sélection d'objets de longueur zéro est créé (l'obtenir à partir d'élément.getSelection (), où element est la div en question). Le focus offset de cet objet vous fera savoir que vous avez cliqué sur, par exemple, le 74ème caractère de cette div (C'est la chose qui Adrien dit était impossible dans une réponse différente).
Lire la position de caret dans le texte et ensuite définir la position de caret dans votre fenêtre d'édition.