Я немного покопался и, к сожалению, не вижу обходного пути ... Хотя одна вещь, которую я заметил при отладке javascript, похоже, что проблема на самом деле связана с самим объектом диапазона, а не с последующим range.select()
. Если вы посмотрите на значения объекта диапазона, которые возвращает selection.createRange()
, то да, родительский объект dom может быть верным, но информация о позиционировании уже ссылается на начало следующей строки (т.е. offsetLeft / Top, boundingLeft / Top и т. Д. уже ошиблись).
Основываясь на информации здесь , здесь и здесь , я думаю, вам не повезло с IE, поскольку у вас есть доступ только к TextRange от Microsoft объект, который кажется сломанным. Из моих экспериментов вы можете переместить диапазон вокруг и расположить его точно так, как он должен быть, но как только вы это сделаете, объект диапазона автоматически сместится вниз на следующую строку, даже прежде чем вы попытаетесь .select()
его. Например, вы можете увидеть проблему, поместив этот код между вашими шагами 1 и 2:
if (range.boundingWidth == 0)
{
//looks like its already at the start of the next line down...
alert('default position: ' + range.offsetLeft + ', ' + range.offsetTop);
//lets move the start of the range one character back
//(i.e. select the last char on the line)
range.moveStart("character", -1);
//now the range looks good (except that its width will be one char);
alert('one char back: ' + range.offsetLeft + ', ' + range.offsetTop);
//calculate the true end of the line...
var left = range.offsetLeft + range.boundingWidth;
var top = range.offsetTop;
//now we can collapse back down to 0 width range
range.collapse();
//the position looks right
alert('moving to: ' + left + ', ' + top);
//move there.
range.moveToPoint(left, top);
//oops... on the next line again... stupid IE.
alert('moved to: ' + range.offsetLeft + ', ' + range.offsetTop);
}
Так что, к сожалению, нет никакого способа убедиться, что диапазон находится в правильном месте при повторном выборе.
Очевидно, есть тривиальное исправление вашего кода выше, изменив Шаг 2 следующим образом:
// Step 2 Restore the selection
if (range.select) {
if (range.boundingWidth > 0) {
range.select();
}
} else {
selection.removeAllRanges();
selection.addRange(range);
doc.body.focus();
}
Но, по-видимому, вы действительно хотите сделать что-то между Шагом 1 и Шагом 2 в своем действительном процессе, что включает в себя перемещение выделения, отсюда необходимость его переустановки. Но на всякий случай. :)
Итак, лучшее, что я могу сделать, - это пойти и проголосовать за ошибку, которую вы создали ... Надеюсь, они это исправят.