Насколько я могу судить, в Internet Explorer нет простого способа получить смещение символа из объекта TextRange. Объект W3C Range имеет узел и смещение текста внутри этого узла. IE, кажется, просто имеет смещение пикселей. Существуют методы для создания, расширения и сравнения диапазонов, поэтому можно было бы написать алгоритм для вычисления смещения символа, но я чувствую, что мне что-то не хватает.
Итак, как проще всего рассчитать смещение символа начала Internet Explorer TextRange?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вы можете перебирать свойство 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()]
В этом случае вам лучше использовать bodyTxt.indexOf (txt), и это действительно был мой первый подход. Однако, если текст в диапазоне повторяется где-нибудь, это число сбрасывается. Чтобы было ясно, это смещение внутри узла, содержащего интересующий меня выбор, а не внутри всего тела.
Я обновил свое решение, чтобы принять родительский узел и проверить повторяющийся текст.
Я использую метод, основанный на этой уловке с положением курсора:
// Assume r is a range:
var offsetFromBody = Math.abs( r.moveEnd('character', -1000000) );
Поскольку moveEnd возвращает количество фактически перемещенных символов, смещение теперь должно быть смещением от начала документа. Это отлично работает для тестирования примитивного перемещения курсора, но для расширенного выбора и для получения точного узла, который удерживает привязку диапазона, вам понадобится что-то более сложное:
// 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) );
}
Это должно вернуть правильное смещение текста каретки. Конечно, если вы уже знаете целевой узел или можете предоставить контекст, вы можете пропустить весь беспорядок в циклическом поиске.
Я использовал немного более простое решение, используя значения смещения 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;
}
Вы хотите подсчитать количество символов слева от экрана до начала диапазона?