Смещение символа в Internet Explorer TextRange

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

Итак, как проще всего рассчитать смещение символа начала Internet Explorer TextRange?

Вы хотите подсчитать количество символов слева от экрана до начала диапазона?

Diodeus - James MacFarlane 03.10.2008 00:06
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
4
1
8 311
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Вы можете перебирать свойство 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), и это действительно был мой первый подход. Однако, если текст в диапазоне повторяется где-нибудь, это число сбрасывается. Чтобы было ясно, это смещение внутри узла, содержащего интересующий меня выбор, а не внутри всего тела.

Thom 03.10.2008 00:31

Я обновил свое решение, чтобы принять родительский узел и проверить повторяющийся текст.

Mark Cidade 03.10.2008 01:24

Я использую метод, основанный на этой уловке с положением курсора:

// 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-to-DOM Range из него.

Обновление от 9 августа 2011 г.

Теперь я бы предложил использовать мою собственную библиотеку Стройный, которая по идее похожа на IERange, но гораздо более полно реализована и поддерживается.

Я использовал немного более простое решение, используя значения смещения 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;
}

Другие вопросы по теме