Internet Explorer TextRange中的字符偏移量

时间:2008-10-02 19:34:12

标签: javascript html internet-explorer selection dhtml

据我所知,没有简单的方法可以从Internet Explorer中的TextRange对象中检索字符偏移量。 W3C Range对象具有一个节点,以及该节点内文本的偏移量。 IE似乎只有像素偏移。有创建,扩展和比较范围的方法,因此可以编写一个算法来计算字符偏移量,但我觉得我必须遗漏一些东西。

那么,计算Internet Explorer TextRange开头字符偏移量的最简单方法是什么?

4 个答案:

答案 0 :(得分: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) );
}

这应该返回正确的插入符号文本偏移量。当然,如果您已经知道目标节点,或者能够提供上下文,那么您可以跳过整个循环搜索混乱。

答案 1 :(得分:5)

我建议使用IERange,或者仅使用TextRange - - - DOM Range算法。

2011年8月9日更新

我现在建议使用我自己的Rangy库,它与IERange的想法类似,但更完全实现和支持。

答案 2 :(得分: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;
}

答案 3 :(得分:1)

您可以使用TextRange.text遍历body元素的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;
 }

[Reference for findText()]