Пользователь
0,0
рейтинг
30 марта 2009 в 17:40

Разработка → Range, TextRange и Selection

Многим JavaScript-разработчикам приходилось сталкиваться с объектами, перечисленными в заголовке, например, при решении следующих задач:
— создание визуальных редакторов (wysiwyg),
— поиск в окне браузера,
— выставление BB-кода,
и т.д.

В этой статье автором предпринята попытка собрать перевод документации об этих объектах в одном месте + написать небольшие сопроводительные примеры. Перевод вольный, не дословный, так что если встретите неточность или корявую формулировку — пишите в комментариях.

В целом пост носит справочный характер, и, надеюсь, кому-то упростит разработку.

1. Range


Range — это объект, соответствующий фрагменту документа, который может включать узлы и участки текста из этого документа. Наиболее подробно о Range-объектах изложено в DOM Range.

Чтобы понять о чем речь, обратимся к самому простому случаю Range-объектов, который будет подробно рассмотрен ниже, — к выделениям. В приводимом ниже примере выделите несколько слов в предложении. Тем самым вы будете создавать объекты, похожие на Range. В нашем примере мы получим текстовое содержимое выделяемой вами области.

Ссылка на пример

Но такие области можно создавать не только с помощью пользовательского выделения, но и из JavaScript-сценария, выполняя с ними определенные манипуляции. Однако, написать простой иллюстрирующий код сразу не выйдет, т.к. есть одно НО — Internet Explorer. В Micsosoft создали собственную реализацию — объект TextRange. Разберем каждую реализацию по-отдельности.

1.1 DOM-реализация Range Mozilla Firefox supported Chrome supported Opera supported Safari supported


Range состоит из двух граничных точек (boundary-points), соответствующих началу и концу области. Позиция любой граничной точки определяется в документе с помощью двух свойств: узел (node) и смещение (offset). Контейнером (container) называют узел, содержащий граничную точку. Сам контейнер и все его предки называются родительскими контейнерами (ancestor containers) для граничной точки. Родительский контейнер, включающий обе граничные точки, называют рут-контейнером (root container).

Range nodes

На изображении выше граничные точки выделения лежат в текстовых узлах (#text1 и #text2), которые являются контейнерами. Для левой границы родительскими контейнерами являются #text1, H1, BODY, для правой — #text2, P, BODY. Общий родитель для обоих граничных точек — BODY, этот элемент является рут-контейнером.

Если контейнер является текстовым узлом, то смещение определяется в символах от начала ноды. Если контейнер является элементом (Document, DocumentFragment, Element...), то смещение определяется в дочерних узлах.

Смотрим на иллюстрацию (источник):

Range Example

Граничные точки Range-объекта s1 лежат в текстовых узлах, поэтому смещение задается в символах от начала узла. Для s2 граничные точки расставлены так, что включают весь абзац <p>Blah xyz</p>, поэтому контейнером является элемент BODY, и смещение считается в позициях дочерних узлов.

Range-объекты создаются с помощью метода creareRange, который вызывается в контексте рут-контейнера или документа. Объект при этом создается пустой, и граничные точки задаются методами setStart и setEnd объекта. Смотрим пример:

<div id="ex2">
  <h2>Соз|даем Range-объекта</h2>
  <p>От третье|го символа заголовка до десятого символа это абзаца.</p>
</div>


$domRange = {
  create : function() {
    // Найдем root-контейнер
    var root =  document.getElementById('ex2');
    // Найдем контейнеры граничных точек (в данном случае тестовые)
    var start =  root.getElementsByTagName('h2')[0].firstChild;
    var end =  root.getElementsByTagName('p')[0].firstChild;
    if ( root.createRange ) {
      // Создаем Range
      var rng = root.createRange();
      // Задаем верхнюю граничную точку, передав контейнер и смещение
      rng.setStart( start, 3 );
      // Аналогично для нижней границы
      rng.setEnd( end, 10 );
      // Теперь мы можем вернуть текст, который содержится в полученной области
      return rng.toString();
    } else
      return 'Вероятно, у вас Internet Explorer, смотрите реализацию TextRange ниже';
  }
}


Пример в действии.

Рассмотрим вкратце свойства и методы Range:
  • Свойство commonAncestorContainer вернет ссылку на наиболее вложенный рут-контейнер.
  • Свойство startContainer (endContainer) вернет ссылку на контейнер верхней (нижней) граничной точки.
  • Свойство startOffset (endOffset) вернет смещение для верхней (нижней) граничной точки.
  • Свойство collapsed вернет true, если граничные точки имеют одинаковые контейнеры и смещение (false в противном случае).

  • Метод setStart (setEnd) задает контейнер (ссылка на узел) и смещение (целочисленное значение) для соот-их граничных точек. Пример выше.
  • Методы setStartBefore, setStartAfter, setEndBefore, setEndAfter принимают в качестве единственного аргумента ссылку на узел и устанавливают граничные точки в соот-ии с естественной границей переданного узла. Например:
    <span id="s1">First</span>
    <span id="s2">Second</span>

    var rng = document.createRange();
    // Установит верхнюю граничную точку по левой границе спана #s1
    rng.setStartBefore( document.getElementById('s1') );
    // Установит нижнюю граничную точку по правой границе спана #s2
    rng.setEndAfter( document.getElementById('s2') );

  • Методы selectNode и selectNodeContents позволяют создать Range-объект по границам узла, ссылку на который они принимают в качестве единственного аргумента. При использовании selectNode передаваемый узел также войдет в Range, в то время как selectNodeContents создаст объект только из содержимого узла:
    Select Node
  • Метод collapse объединяет граничные точки Range-объекта. В качестве единственного аргумента принимает булево значение (true &mdash для объединения в верхней точке, false &mdash в нижней). По-умолчанию true.
  • Метод toString вернет текстовое содержимое Range-объекта.
  • Метод cloneContents вернет копию содержимого Range-объекта в виде фрагмента документа.
  • Метод cloneRange вернет копию самого Range-объекта.
  • Метод deleteContents удаляет всё содержимое Range-объекта.
  • Метод detach извлекает текущий объект из DOM, так что на него больше нельзя сослаться.
  • Метод insertNode принимает в качестве единственного аргумента ссылку на узел (или фрагмент документа) и всталяет его в содержимое Range-объекта в начальной точке.
  • Метод extractContents вырезает содержимое Range-объекта и возвращает ссылку на полученный фрагмент документа.
  • Метод surroundContents помещает всё содержимое текущего Range-объекта в новый родительский элемент, ссылка на который принимается в качестве единственного аргумента.
  • Метод compareBoundaryPoints используется для сравнения граничных точек.


Чтобы отвлечься и закрепить знания, решим небольшую задачку. Найдем в текстовом узле фразу и подсветим её синим фоном.

<div id="ex3">
  Найдем в этом тексте слово "бабуля" и подсветим его синим фоном
</div>


$domRange.highlight = function( text ) {
  // Получим текстовый узел
  var root = document.getElementById('ex3').firstChild;
  // и его содержимое
  var content = root.nodeValue;
  // Проверим есть ли совпадения с переданным текстом
  if ( content.indexOf( text ) != -1 ) {
    if ( document.createRange ) {
      // Если есть совпадение, и браузер поддерживает Range, создаем объект
      var rng = document.createRange();
      // Ставим верхнюю границу по индексу совпадения,
      rng.setStart( root, content.indexOf( text ) );
      // а нижнюю по индексу + длина текста
      rng.setEnd( root, content.indexOf( text ) + text.length );
      // Создаем спан с синим фоном
      var highlightDiv = document.createElement('span');
      highlightDiv.style.backgroundColor = 'blue';
      // Обернем наш Range в спан
       rng.surroundContents( highlightDiv );
    } else
      alert('Вероятно, у вас Internet Explorer, смотрите реализацию TextRange ниже');
  } else
    alert('Совпадений не найдено');
}


Пример в действии.

С остальными свойствами и методами поэкспериментируйте сами.
Перейдем к реализации range в MSIE.

1.2. TextRange Internet Explorer supported


Объект TextRange в реализации MSIE — это текстовый диапазон нулевой и более длины. У данного диапазона также есть свои границы, «перемещать» которые можно на целое число текстовых едениц: character(символ), word (слово), sentence (предложение). То есть можно взять и сдвинуть границу на 2(5, 8 и т.д.) слова (символа, предложения) вправо (влево). При этом у объекта сохраняются данные о HTML-содержимом диапазона и есть методы взаимодействия с DOM.

Объект TextRange создается с помощью метода createTextRange, который можно вызывать в контексте следующих DOM-элементов:

BODY, BUTTON, INPUT type=button, INPUT type=hidden, INPUT type=password, INPUT type=reset, INPUT type=submit, INPUT type=text, TEXTAREA

Простой пример с кнопкой:

<input id="buttonId" type="button" value="Test button" />

$ieTextRange = {
  create : function() {
    // Найдем кнопку
    var button = document.getElementById('buttonId');
    // Если мы в ИЕ
    if ( button.createTextRange && button.createTextRange() != undefined ) {
      // Создаем TextRange
      var rng = button.createTextRange();
      // И вернем текстовое содержимое полученного объекта
      return rng.text;
    } else
      return 'Вероятно, у вас не IE (поздравляем!), смотрите реализацию Range выше';
  }
}


Пример в действии.

Рассмотрим свойства и методы объекта TextRange (не все, только самые необходимые):
  • Свойство boundingWidth (boundingHeight) вернет ширину (высоту), которую занимает объект TextRange в пикселях.
  • Свойство boundingTop (boundingLeft) вернет Y(X)-координату верхнего левого угла тестовой области относительно окна документа.
  • Свойство htmlText вернет HTML-содержимое объекта.
  • Свойство text вернет текстовое содержимое объекта (см. пример выше).
  • Свойство offsetTop (offsetLeft) вернет Y(X)-координату верхнего левого угла тестовой области относительно предка.

  • Метод collapse объединяет граничные точки диапазона. В качестве единственного аргумента принимает булево значение (true &mdash для объединения в верхней точке, false &mdash в нижней). По-умолчанию true.
  • Метод duplicate клонирует имеющийся текстовый диапазон, возвращая новый, точно такой же.
  • Метод expand расширяет текущий тектовый диапазон до еденицы текста, переданной в качестве единственного текстового аргумента:
    'character' — символ
    'word' — слово
    'sentence' — предложение
    'textedit' — сворачивает до первоначального диапазона.

    Вернет true (false) в случае успеха (неудачи).
  • Метод findText ищет в диапазоне совпадения с текстовой строкой, передаваемой в качестве первого аргумента (без учета регистра). Если совпадение найдено, то границы диапазона сворачиваются до него. В качестве второго (необязательного) аргумента можно передать целое число, указывающее число символов от верхней точки, в которых нужно производить поиск. Далее в качестве аргументов можно перечислять INT-флаги, которые вам вряд ли понадобятся.
  • Метод getBookmark возвращает в случае успешного вызова строку, по которой можно будет восстановить текущее состояние текстового диапазона с помощью метода moveToBookmark.
  • Метод inRange принимает в качестве аргумента другой TextRange-объект и проверяет, входит ли его текстовый диапазон в диапазон контекстного объекта. Возвращает булево значение.
  • Метод isEqual проверяет является ли текущий TextRange-объект идентичным переданному в качестве аргумента. Возвращает булево значение.
  • Метод move(sUnit [, iCount]) сворачивает текущий диапазон до нулевой длины и передвигает на еденицу текста, переданного в качестве первого аргумента (character | word | sentence | textedit). В качестве второго (необязательного) аргумента можно передать число едениц, на которое следует передвинуть диапазон.
  • Метод moveEnd (moveStart), аналогично методу move, передвигает верхнюю (нижнюю) границу диапазона на еденицу текста, число которых также можно задать необязательным вторым параметром.
  • Метод moveToElementText принимает в качестве аргумента ссылку на DOM-элемент и выставляет границы диапазона TextRange-объекта по границам полученного элемента.
  • Метод moveToPoint принимает в качестве двух обязательных аргументов X и Y-координаты (в пикселях) относительно верхнего левого угла документа и переносит границы диапазона туда.
  • Метод parentElement вернет ссылку на элемент, который полностью содержит диапазон TextRange-объекта (или null).
  • Метод pasteHTML заменяет HTML-содержимое текущего текстового диапазона на строку, переданную в качестве единственного аргумента.
  • Метод select формирует выделение на основе содержимого TextRange-объекта, о чем мы подробнее поговорим ниже.
  • Метод setEndPoint принимает в качестве обязательных аргументов текстовый указатель и ссылку на другой TextRange-объект, устанавливая в зависимости от значения указателя границы диапазона. Указатели могут быть следующими: 'StartToEnd', 'StartToStart', 'EndToStart', 'EndToEnd'.


Также к TextRange-объектам применимы команды метода execCommand.

Для закрепления решим задачку по поиску текстового содержимого, аналогичную той, что была выше:

<div id="ex4">
  Найдем в этом тексте слово "бабуля" и подсветим его синим фоном
</div>


$ieTextRange.highlight = function( text ) {
  // Получим ссылку на элемент, в котором будет происходить поиск
  var root = document.getElementById('ex4');
  // Получим значение его текстового потомка
  var content = root.firstChild.nodeValue;
  // Если есть совпадение
  if ( content.indexOf( text ) != -1 ) {
    // и мы в MSIE
    if ( document.body.createTextRange ) {
      // Создадим объект TextRange
      var rng = document.body.createTextRange();
      // Свернем его до root
      rng.moveToElementText( root );
      // Найдем текст и свернем диапазон до него
      if ( rng.findText( text ) )
        // Заменим текстовый фрагмент на span с синим фоном
        rng.pasteHTML( '<span style="background:blue;">' + text + '</span>' );
    } else
      alert('Вероятно, у вас не IE (поздравляем!), смотрите реализацию Range выше');
  } else
    alert('Совпадений не найдено');
}


Пример в действии.

С остальными свойствами и методами поэкспериментируйте сами.

2. Selection


Всем знакомо выделение элементов на странице, когда, зажав левую кнопку мыши и передвигая курсор, мы выделяем нужный фрагмент. Или зажимаем Shift и жмем на стрелочки клавиатуры. Или еще как-то, неважно. В данной части статьи мы кроссбраузерно научимся решать две задачи: получать пользовательское выделение и устанавливать собственное.

2.1. Получаем пользовательское выделение


Эту задачу мы уже решали в самом начале статьи в примере с миксом. Теперь рассмотрим код:

$selection = {
  getText : function() {
    var txt = '';
    if (txt = window.getSelection) // Not IE, используем метод getSelection
      txt = window.getSelection().toString();
    else // IE, используем объект selection
      txt = document.selection.createRange().text;
    return txt;
  }
}


Все браузеры, кроме Internet Explorer поддерживают метод getSelection в контексте window, который возвращает объект, схожий с рассмотренным ранее Range. У этого объекта есть точка начала выделения (anchor) и фокусная точка окончания (focus). Точки могут совпадать. Рассмотрим свойства и методы Selection-объекта: Mozilla Firefox supportedChrome supportedOpera supportedSafari supported
  • Свойство anchorNode вернет контейнер, в котором начинается выделение. Замечу, что началом выделения считается та граница, от которой вы начали выделение. То есть, если вы выделяете справа налево, то началом будет именно правая граница. Это правило работает везде, кроме браузера Opera, в котором anchorNode вернет ссылку на узел левого края выделения.
  • Свойство anchorOffset вернет смещение для начала выделения в пределах контейнера anchorNode.
  • Свойства focusNode и focusOffset работают аналогично для фокусных точек, то есть точек окончания выделения. Opera и здесь отличилась, возвращает вместо фокусной точки узел правого края выделения.
  • Свойство rangeCount возвращает число Range-объектов, которые входят в полученное выделение. Это свойство полезно при использовании метода addRange.

  • Метод getRangeAt принимает в качестве аргумента индекс Range-объекта и возвращает сам объект. Если rangeCount == 1, то работать будет только getRangeAt(0). Таким образом, мы можем получить Range-объект, полностью соответствующий текущему выделению.
  • Метод collapse сворачивает выделение в точку (каретку). Методу можно передать в качестве первого аргумента узел, в который нужно поместить каретку.
  • Метод extend принимает в качестве аргументов ссылку на контейнер и смещение (parentNode, offset), и перемещает фокусную точку в это положение.
  • Метод collapseToStart (collapseToEnd) перемещает фокусную (начальную) границу к начальной (фокусной), тем самым сворачивая выделение в каретку.
  • Метод selectAllChildren принимает в качестве единственного аргумента ссылку на узел и добавляет всех его потомков в выделение.
  • Метод addRange принимает в качестве аргумента Range-объект и добавляет его в выделение. Таким образом можно увеличить количество Range-объектов, число которых нам подскажет свойство rangeCount.
  • Метод removeRange (removeAllRanges) удаляет переданный (все) Range-объект из выделения.
  • Метод toString вернет текстовое содержимое выделения.

Internet Explorer предоставляет собственный интерфейс взаимодействия с выделениями — объект selection в контексте document. Для работы с этим объектом используются следующие методы Internet Explorer supported
  • Метод clear убирает выделение вместе с содержимым.
  • Метод createRange (ВАЖНО! Не путать с DOM-методом createRange для создания Range-объектов!) создает из содержимого выделения TextRange-объект.
  • Метод empty убирает выделение, но оставляет содержимое.

Надеюсь, теперь, после знакомства с обеими реализациями выделений, код выше стал более понятен.

2.1. Установка собственного выделения


Допустим, вам хочется, чтобы какой-то текстовый фрагмент на странице был выделен, как пользовательское выделение. Это нужно при клиентской реализации поиска по странице и некоторых других задач. Проще всего решить эту задачу следующим образом:
  1. Создать Range-объект (TextRange для IE).
  2. Перевести полученный объект в выделение.

Смотрим реализацию:

<div id="ex5">
  Снова будем выделять <span>бабулю</span>, на этот раз без поиска.
</div>


$selection.set = function() {
  var target = document.getElementById('ex5').getElementsByTagName('span')[0];
  var rng, sel;
  if ( document.createRange ) {
    rng = document.createRange();
    rng.selectNode( target )
    sel = window.getSelection();
    sel.removeAllRanges();
    sel.addRange( rng );
  } else {
    var rng = document.body.createTextRange();
    rng.moveToElementText( target );
    rng.select();
  }
}


Пример в действии.

3. Послесловие


Осмысливая в процессе написания статьи предоставляемое API, возникла идея создать небольшую библиотеку, которая научит IE DOM-реализации Range и Selection. Возможно, она даже существует, тогда автор вам будет благодарен за ссылку и экономию собственного времени.

Описание API не претендует на полноту и точность перевода, но автору этого вполне достаточно для комфортной JavaScript-разработки. С оригиналами на английском вы можете ознакомиться по ссылкам ниже.

Кросспост статьи Range, TextRange и Selection с fastcoder.org.

4. Ссылки

Александр @bur
карма
104,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (28)

  • +2
    Ух, как здорово! Спасибо!
    • +1
      Вэлкам!
      Размочим нулевое количество комментов :-)
      Хотя, к справочным данным особо ничего в догонку не напишешь…
      • +2
        Ну можно начать ругать эксплорер за собственые реализации.
        • 0
          Тесты в stable-версии ИЕ8 показали, что ребята из Силиконовой долины перенесли реализацию TextRange в свой флагман. Так что статья будет еще долгое время актуальной.

          DOM-реализации Range автор там не нашел. Может плохо искал?
          • 0
            Ну поэтому я и говорил, что можно начать ругать)
            Кстати, майкрософт можно приводить в пример велосипедистам.
        • 0
          Меду так прочим такой обьект появился вначале в ие а потом уже и у других браузеров только почемуто с совершенно другим интерфейсом.
        • 0
          В IE реализация работы с выделениями лучше.
          Легко посчитать размеры в пикселях занятые под выделение.
          Одинаковая логика работы с выделениями что внутри input-ах с textarea-ми, что вне их.
          Единственный минус тот же что и в innerHTML — не работает правильно вставка содержимого внутри таблиц, списков и т.п. и возвращает творчески переосмысленный html код выделенного.
          • 0
            Для решения каких задач вам нужно знать число пикселей под выделением? :-)

            В целом, DOM-реализация Range мне нравится тем, что граничные точки теснее привязаны к DOM. Это удобнее, чем манипулировать текстовыми смещениями.

            Хотя вопрос удобства той или иной реализации можно решить только на примере конкретных практических задач. Абстрактные рассуждения, имхо, не уместны.
            • 0
              реальная задача, разбить длинное (в пикселях) слово, чоб не уползало за экран.
              Это вам кажется что удобно, привязка текста к DOM элементам. Это две независящие друг от друга стихии… вот удалите вы DOM элемент в котором стартует выделение и что? придется сохраненный ранее бекап выделения придется переосмысливать.
              • 0
                Задачу, которую вы привели в пример, не стоит решать через Range (если я конечно правильно понял суть):
                fastcoder.org/articles/?aid=183

                С удалением DOM-элементов, если этим занимается скрипт, а не пользователь, конечно, беда. Придется проверять не является ли элемент контейнером анкора/фокуса и переносить граничную точку в родительский узел. Из комментов ниже я понял, что в ИЕ для этого букмарки сделали.
  • 0
    Давно пора об этом было поговорить :)
  • 0
    Супер и материал и оформление!
  • 0
    Спасибо большое, очень давно интересовал этот вопрос, но руки не доходили разобраться. Было бы просто великолепно, если бы вы написали еще про создание простейшего wysiwyg редактора.
    • 0
      Вэлкам!
      Про простейший висивик есть даже одноименная статья:
      fastcoder.org/articles/?aid=169
  • 0
    Вэлкам!
    Про простейший висивик есть даже одноименная статья:
    fastcoder.org/articles/?aid=169
  • 0
    может автор подскажет как при вызове таких функций как InsertUnorderedList (или к примеру функции зачистки html кода) сохранить выделение/положение курсора? перепробывал кучу всяких вариантов — ничего толкового…
    • 0
      Вероятно, вы имеете в виду команду «InsertUnorderedList» метода execCommand?

      На вскидку, можно попробовать сохранять выделение(фокус) в виде Range(TextRange)-объекта, производить манипуляцию, а затем восстанавливать фокус из сохраненного объекта. Примерно так:

      // Получим выделение (фокус)
      var sel = window.getSelection? window.getSelection(): document.selection;
      // Создадим из него Range(TextRange)-объект
      var rng = window.getSelection? sel.getRangeAt(0): sel.createRange();
      // На всякий случай сделаем клон
      var rngClone = window.getSelection? rng.cloneRange(): rng.duplicate();
      /*
      Здесь выполним нужную команду метода execCommand
      */
      // Восстановим фокус из клона
      if ( window.getSelection ) {
      sel = window.getSelection();
      sel.removeAllRanges();
      sel.addRange( rngClone );
      } else rngClone.select();

      Набивал прямо здесь без проверки, так что возможны ошибки, да и код можно оптимизировать. Но направление мыслей должно быть понятным…
      • 0
        все бы хорошо, но в range сохраняется контейнер и смещение — которых после операции может попросту не быть, или смещение может быть уже совсем другим…

        из того что я рыл в коде тини — они оставляют некие букмарки\якоря по которым потом востанавливают выделение — но как это сделано там я так и не смог осилить…
        • 0
          Если используемая вами команда занимается вставкой данных, то описанный выше скрипт должен справляться.

          В контексте объекта TextRange можно вызвать метод getBookmark(), который вернет строку (там свой внутренний формат какой-то). Позже, скормив эту строку методу moveToBookmark(), вы можете восставновить фокус. Это, кстати, описано в статье. Работает в ИЕ соот-но.

          Аналогичного интерфейса в DOM Range не встречал, используйте стандартные свойства и методы.
  • 0
    Коллективный разум существует? Вчера искал инфу по установке пользовательских выделений, но все на что натыкался в основном было про текст в инпутах. И вчера же появляется ваша статья здесь, в которой всё доходчиво изложено. Спасибо за труд.
    • 0
      Эту статью я начал писать в феврале, когда окончательно надоело собирать API по пяти разным ссылкам. Недавно дописал и выложил на fastcoder.org. Ну а потом подумалось, что материал будет полезен хабровчанам. Хорошо, что не ошибся :-)
      • 0
        Огромное спасибо Вам. Сам недавно ковырялся по частям разных документаций по Range (нужно было с FCK Editor дёргать положение курсора), и это ужасно надоедало.
  • 0
    Думаю, было бы полезно добавить инфу о том, как выделить/получить выделение текстбокса.

    Например, выделить символы со второго до предпоследнего:

    input.select();
    input.selectionStart = 1;
    input.selectionEnd = input.value.length — 1;
  • 0
    Хорошая статья, до сих пор к ней возвращаюсь (пишу визуальный редактор)
  • 0
    Автор, подскажите пожалуйста, как быть в моем случае?
    Мне нужно получить текст только из одного узла. Т.е. если имеется div, внутри которого есть текст, то при выделении и нажатии на кнопку я хочу, чтобы выделение идентифицировалось только в случае если оно находится в этом div.
    Вот так я получаю выделение ото всюду. Но ведь getSelection() — метод window, а следовательно его я не могу заменить его на свой узел.

    var selection = window.getSelection().getRangeAt(0);

    Буду благодарен за помощь.
  • 0
    Есть еще либа для таких нужд: code.google.com/p/rangy/

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