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?

Était-ce utile?

La solution

Je suggérerais IERange , ou simplement le TextRange -to- DOM Range son algorithme.

Mise à jour du 9 août 2011

Je suggérerais maintenant d'utiliser ma propre bibliothèque Rangy , qui est similaire à l'idée IERange mais beaucoup plus pleinement réalisé et soutenu.

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;
 }

[ Référence pour findText () ]

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top