4

私が知る限り、Internet Explorer で TextRange オブジェクトから文字オフセットを取得する簡単な方法はありません。W3C Range オブジェクトには、ノードと、そのノード内のテキストへのオフセットがあります。IEにはピクセルオフセットがあるようです。範囲を作成、拡張、比較する方法があるため、文字オフセットを計算するアルゴリズムを作成することは可能ですが、何かが足りないと感じています。

では、Internet Explorer の TextRange の開始位置の文字オフセットを計算する最も簡単な方法は何でしょうか?

4

4 に答える 4

8

このキャレット位置のトリックに基づく方法を使用します。

// Assume r is a range:
var offsetFromBody = Math.abs( r.moveEnd('character', -1000000) );

moveEnd は実際に移動した文字数を返すため、offset はドキュメントの先頭からのオフセットになります。これは、プリミティブ キャレットの動きをテストする場合には問題なく機能しますが、選択範囲を拡張し、範囲アンカーを保持する正確なノードを取得するには、もっと複雑なものが必要になります。

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

これにより、正しいキャレット テキスト オフセットが返されます。もちろん、ターゲットノードがすでにわかっている場合、またはコンテキストを提供できる場合は、ループ検索の混乱全体をスキップできます。

于 2008-10-13T18:03:24.037 に答える
5

I'd suggest IERange, or just the TextRange-to-DOM Range algorithm from it.

Update, 9 August 2011

I'd now suggest using my own Rangy library, which is similar in idea to IERange but much more fully realized and supported.

于 2009-04-26T01:30:56.597 に答える
2

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;
}
于 2010-03-25T12:57:38.793 に答える
1

を使用して body 要素のTextRange.textプロパティを反復処理しString.substring()、文字オフセットが必要な TextRange と比較できます。

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

の参考資料findText()

于 2008-10-02T20:13:54.147 に答える