Caractère décalé dans un Internet Explorer TextRange
-
03-07-2019 - |
Question
Autant que je sache, il n’existe pas de moyen simple de récupérer un décalage de caractère à partir d’un objet TextRange dans Internet Explorer. L'objet Range du W3C a un nœud et le décalage dans le texte au sein de ce nœud. IE semble avoir juste des décalages de pixels. Il existe des méthodes pour créer, étendre et comparer des plages. Il est donc possible d’écrire un algorithme pour calculer le décalage de caractère, mais j’ai le sentiment que quelque chose me manque.
Alors, quel est le moyen le plus simple de calculer le décalage de caractère du début d’un Internet Explorer TextRange?
Autres conseils
J'utilise une méthode basée sur ce tour de caret:
// Assume r is a range:
var offsetFromBody = Math.abs( r.moveEnd('character', -1000000) );
Étant donné que moveEnd renvoie le nombre de caractères réellement déplacés, le décalage doit maintenant être le décalage par rapport au début du document. Cela fonctionne bien pour tester le mouvement de curseur primitif, mais pour les sélections étendues et pour obtenir le nœud exact qui contient l'ancre de distance, vous aurez besoin de quelque chose de plus complexe:
// where paramter r is a range:
function getRangeOffsetIE( r ) {
var end = Math.abs( r.duplicate().moveEnd('character', -1000000) );
// find the anchor element's offset
var range = r.duplicate();
r.collapse( false );
var parentElm = range.parentElement();
var children = parentElm.getElementsByTagName('*');
for (var i = children.length - 1; i >= 0; i--) {
range.moveToElementText( children[i] );
if ( range.inRange(r) ) {
parentElm = children[i];
break;
}
}
range.moveToElementText( parentElm );
return end - Math.abs( range.moveStart('character', -1000000) );
}
Ceci devrait renvoyer le décalage correct du texte du curseur. Bien sûr, si vous connaissez déjà le nœud cible ou si vous êtes en mesure de fournir un contexte, vous pouvez ignorer tout le bazar de recherche en boucle.
J'ai utilisé une solution légèrement plus simple en utilisant les valeurs de décalage d'un textRange:
function getIECharOffset() {
var offset = 0;
// get the users selection - this handles empty selections
var userSelection = document.selection.createRange();
// get a selection from the contents of the parent element
var parentSelection = userSelection.parentElement().createTextRange();
// loop - moving the parent selection on a character at a time until the offsets match
while (!offsetEqual(parentSelection, userSelection)) {
parentSelection.move('character');
offset++;
}
// return the number of char you have moved through
return offset;
}
function offsetEqual(arg1, arg2) {
if (arg1.offsetLeft == arg2.offsetLeft && arg1.offsetTop == arg2.offsetTop) {
return true;
}
return false;
}
Vous pouvez parcourir la propriété TextRange.text
de l'élément body en utilisant String.substring ()
pour comparer le TextRange pour lequel vous souhaitez le décalage de caractère.
function charOffset(textRange, parentTextRange)
{ var parentTxt = parentTextRange.text;
var txt = textRange.text;
var parentLen = parentTxt.length;
for(int i=0; i < parentLen ; ++i)
{ if (parentTxt.substring(i, txt.length+i) == txt)
{ var originalPosition = textRange.getBookmark();
//moves back one and searches backwards for same text
textRange.moveStart("character",-1);
var foundOther = textRange.findText(textRange.text,-parentLen,1);
//if no others were found return offset
if (!foundOther) return i;
//returns to original position to try next offset
else textRange.moveToBookmark(originalPosition);
}
}
return -1;
}