Оглавление

17.15. Объект TextRange.

Поиск фрагмента в текстовом поле или документе. Расширение или сжатие выделенного фрагмента текста

 

Объект TextRange предоставляет доступ к фрагменту текста Web-страницы. Для работы с фрагментом необходимо создать объект с помощью метода createTextRange() :

    var Text1 = document.body.createTextRange();


Свойства объекта TextRange:
□  text возвращает текстовый фрагмент;
□  htmiText возвращает HTML-код содержимого объекта;
□  boundingHeight и boundingwidth служат для определения высоты и ширины прямоугольника, содержащего текстовую область;
□  boundingLeft и boundingTop позволяют определить горизонтальную и вертикальую координаты левого верхнего угла прямоугольника, содержащего текстовую  область,  относительно  элемента,   содержащего  объект TextRange;
□  offsetLeft и offsetTop возвращают горизонтальную и вертикальную координаты левого верхнего угла прямоугольника, содержащего текстовую область, относительно окна.

 

Методы объекта TextRange:
□ select() выделяет содержимое объекта TextRange;
□ pasteHTML(<текст>) заменяет текущее содержимое объекта TextRange на HTML-фрагмент, указанный в качестве параметра;
□ findText(<текст>) проверяет наличие заданного текста внутри объекта TextRange. Возвращает true, если текст был найден:
□ scrollIntoview() прокручивает содержимое окна так, чтобы объект был виден в окне;
□ expand(<Элемент>) расширяет объект TextRange на один <Элемент>. Возвращает true, если объект был расширен, и false — в противном случае;
□ move (<Элемент>, <Количество>) сжимает объект в точку и перемещает его на заданное <Количество> <Элементов>. <Количество> может принимать положительные или отрицательные значения. Если оно не задано, то объект сдвигается на один <Элемент>;
□ moveStart(<Элемент>, <Количество>) перемещает начальную границу объекта на заданное <Количество> <Элементов>;
□ moveEnd(<Элeмeнт>, <Количество>) перемещает конечную границу объекта на заданное <Количество> <Элементов>.

          В качестве <Элемента> могут быть заданы следующие строковые значения:
          •      character — символ;
          •      word — слово;
          •      sentence — предложение;
          •      textedit — область объекта;
□ collapse(true | false) сворачивает объект TextRange, то есть помещает открывающие и закрывающие маркеры объекта TextRange вместе в начало или конец текущего объекта. Если параметр равен true, то маркеры помещаются в начало, если false — то в конец. Используется для установки маркера ввода в нужную позицию;
□ moveToPoint(<х>, <у>) передвигает границы объекта и сжимает его вокруг выбранной точки. Координаты отсчитываются относительно окна;
□ moveToElementText(<Элемент страницы>) перемещает объект так, чтобы он охватил текст в заданном элементе;
□ duplicate() возвращает новый объект TextRange, являющийся копией текущего;

□ parentEiement () возвращает ссылку на родительский элемент, содержащий текущий объект TextRange;
□ inRange(<объект>) равен true, если указанный объект содержится внутри текущего;
□ isEqual (<объект>) равен true, если указанный объект равен текущему;
□ getBookmark() создает закладку;
moveToBookmark(<Закладка>)   переходит к закладке.  Возвращает true, если переход прошел успешно;
□ compareEndPoints(<Диапазон>, <Объект>)   сравнивает два объекта по указанному <Диапазону>. Возвращает следующие значения:
          •    -1 — если граница текущего находится левее или выше границы указанного объекта;
          •     0 — если они равны;
          •     1 — если граница текущего находится правее или ниже границы указанного объекта.

      В качестве <Диапазока> могут быть указаны следующие строковые значения:

          •     StartToEnd — сравнение начальной границы текущего объекта с конечной границей указанного объекта;
          •     StartToStart — сравнение начальной границы текущего объекта с начальной границей указанного объекта;
          •     EndToStart — сравнение конечной границы текущего объекта с начальной границей указанного объекта;
          •     EndToEnd — сравнение конечной границы текущего объекта с конечной границей указанного объекта;
setEndPoint(<Диапазон>, <Объект>)   переносит начальную или конечную границу текущего объекта в начало или конец заданного объекта.

     В качестве <Диапазона> могут быть указаны следующие значения:
          •     StartToEnd совмещает начальную границу текущего объекта с конечной границей указанного объекта;
          •     StartToStart совмещает начальную границу текущего объекта с начальной границей указанного объекта;

          •     EndToStart совмещает конечную границу текущего объекта с начальной границей указанного объекта;
          •     EndToEnd совмещает конечную границу текущего объекта с конечной границей указанного объекта.

 

В качестве примера в листинге 62 реализована возможность поиска фрагмента в текстовой области.

 

Листинг 62. Поиск фрагмента в текстовой области


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
         "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
 <title>Поиск фрагмента</title>
 <meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<script type="text/javascript">
<!--
function f_click() {
   if (!document.getElementById("txt2").createTextRange) {
      window.alert("Объект не поддерживается Web-браузером");
      return;
   }
   var Range1, Text1, Select1;
   Text1 = document.getElementById("txt1").value;
   Select1 = document.getElementById("sel1")
   if (Text1 != "") {
      Range1 = document.getElementById("txt2").createTextRange();
      if (Range1.findText(Text1)) {
         Range1.scrollIntoView();
         switch (Select1.value) {
         case "1": 
            Range1.expand("character"); break;
         case "2": 
            Range1.expand("word"); break;
         case "3": 
            Range1.collapse(true); break;
         case "4": 
            Range1.collapse(false); break;
         case "5":
            Range1.expand("word");
            Range1.collapse(true);
            break;
         case "6": 
            Range1.expand("word");
            Range1.collapse(false);
            break;
         }
         Range1.select(); // Выделяем найденный фрагмент
         var msg = "bounding X: " + Range1.boundingLeft;
         msg += " bounding Y: " + Range1.boundingTop + "<br>";
         msg += "offset X: " + Range1.offsetLeft;
         msg += " offset Y: " + Range1.offsetTop + "<br>";
         msg += "Тег: " + Range1.parentElement().tagName;
         msg += " id: " + Range1.parentElement().id + "<br>";
         document.getElementById("div1").innerHTML = msg;
      }
      else window.alert("Ничего не найдено");
   }
   else window.alert("Поле не заполнено");
}
//-->
</script>
</head>
<body>
<div>
<input type="text" id="txt1"><br>
<select id="sel1">
<option value="0">Выделить текст</option>
<option value="1">Выделить текст + 1 символ</option>
<option value="2">Выделить все слово</option>
<option value="3">Поместить курсор в начало найденного фрагмента</option>
<option value="4">Поместить курсор в конец найденного фрагмента</option>
<option value="5">Поместить курсор в начало слова с фрагментом</option>
<option value="6">Поместить курсор в конец слова с фрагментом</option>
</select><br>
<input type="button" value="Найти" onclick="f_click();"><br>
<script type="text/javascript">
<!--
document.write("<textarea id='txt2' cols='50' rows='10'>");
for (var i=1; i<51; i++) {
   document.write("Содержимое строки" + i + "\n");
}
document.write("<" + "/textarea>");
//-->
</script>
</div>
<div id="div1"></div>
</body>
</html>

 

А следующий пример демонстрирует применение методов movestarto и moveEnd(). С помощью кнопок можно перемещать начальную или конечную границу объекта TextRange, таким образом расширяя или сжимая выделенный фрагмент (листинг 63).

 

Листинг 63. Расширение выделенного фрагмента


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
         "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
 <title>Расширение выделенного фрагмента</title>
 <meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<script type="text/javascript">
<!--
function f_click(Val1) {
   if (!document.selection) {
      window.alert("Объект не поддерживается Web-браузером");
      return;
   }
   if (document.selection.type=="Text") {
      var Range1 = document.selection.createRange();
      switch (Val1) {
        case 1:
           Range1.moveStart("character", -1);
           Range1.select();
           break;
        case 2:
           Range1.moveStart("character");
           Range1.select();
           break;
        case 3:
           Range1.moveEnd("character", -1);
           Range1.select();
           break;
        case 4:
           Range1.moveEnd("character");
           Range1.select();
           break;
      }
   }
   else {
      window.alert("Необходимо выделить фрагмент");
   }
}
//-->
</script>
</head>
<body>
<p>Расширение выделенного фрагмента</p>
<div>
Начальная граница 
<input type="button" value=" &lt; " onclick="f_click(1);">
<input type="button" value=" &gt; " onclick="f_click(2);"><br>
Конечная граница 
<input type="button" value=" &lt; " onclick="f_click(3);">
<input type="button" value=" &gt; " onclick="f_click(4);">
</div>
</body>
</html>

 

В Web-браузерах Firefox и Opera поддерживается абсолютно другой объект, называемый Range. Для работы с таким объектом необходимо создать область с  помощью метода createRange() объекта document:

   var rng = document.createRange();


Свойства объекта Range:
□   startContainer возвращает ссылку на узел, в котором содержится начальная точка области;
□  startOffset возвращает смещение от начала узла (возвращаемого свойством startContainer) до начальной точки области;
□  endContainer возвращает ссылку на узел, в котором содержится конечная точка области;
□  endoffset возвращает смещение от начала узла (возвращаемого свойством endContainer) до конечной точки области;
□  collapsed возвращает true, если объект свернут в точку, и false — в противном случае:

   var rng = document.createRange();
   if (rng.collapsed) window.alert("Свернут");
   else window.alert("Нет");

□  commonAncestorContainer возвращает ссылку на узел, в котором содержатся как начальная, так и конечная точки области.

 

Методы объекта Range:
□  toString() возвращает текстовое содержимое области;
□  cloneRange() создает копию объекта Range;
□  cloneContents()   создает   копию   внутреннего   содержимого   области. В качестве значения возвращает объект DocumentFragment;
□  detach() удаляет объект Range;
□  deietecontents() удаляет все внутреннее содержимое области из документа;

□  extractcontents() удаляет все внутреннее содержимое области из документа и возвращает объект DocumentFragment, в котором будет находиться удаленное содержимое области;
□  collapse(<true | false>) сворачивает область в указанную точку. Если в качестве параметра указано значение true, то область сворачивается в начальную точку, а если false — то в конечную точку;
□  seiectNode(<Узел>) ограничивает область указанным в качестве параметра узлом;
□  seiectNodeContents(<Узел>) ограничивает область внутренним содержимым указанного узла;
□  insertNode(<Узел>) вставляет новый узел в начало области;
□  setStart(<Узел>, <Смещение>) устанавливает положение начальной точки области;
□  setStartBefore(<Узел>) устанавливает начальную точку области перед указанным узлом;
□  setstartAfter(<Узел>) устанавливает начальную точку области после указанного узла;

□  setEnd(<Y3en>; <Смещение) устанавливает положение конечной точки области;
□  setEndBefore(<Узел>) устанавливает конечную точку области перед указанным узлом;
□  setEndAfter(<Узел>) устанавливает конечную точку области после указанного узла;
□  surroundСontents(<Узел>) вкладывает содержимое области в указанный узел;
□  compareBoundaryPoints(<Точки сравнения>, <Область, с которой сравниваем>) сравнивает позиции двух областей. В качестве первого параметра могут быть указаны следующие значения:
          •     о — START_TO_START — сравнение начальных точек;
          •     1 — START_TO_END — сравнение начальной точки области, указанной в качестве второго параметра, с конечной точкой данной области;
          •     2 — END_TO_END — сравнение конечных точек;
          •     з — END_TO_START — сравнение конечной точки области, указанной в качестве второго параметра, с начальной точкой данной области.

 

В качестве примера использования объекта Range найдем внутри абзаца текст "фрагмент" и вложим его в тег <strong>:


<p id="txt">Текст для выделения фрагмента</p>
<input type="button" id="btn1" onclick="f_click()" value="Выделить">
<script type="text/javascript">
function f_click() {
   if (document.createRange) {
      var p = document.getElementById("txt").firstChild;
      var text = p.nodeValue; // Получаем текст абзаца
      var ind = text.indexOf("фрагмент");
      if (ind != -1) { // Если текст найден
         // Создаем объект Range
         var rng = document.createRange();
         rng.setStart(p, ind); // Начальная точка
         // Конечная точка
         rng.setEnd(p, ind + 8);
         // Элемент, в который будем вкладывать текст
         var s = document.createElement("strong");
         // Вкладываем область в тег strong
         rng.surroundContents(s);
      }
   }
   else {
      window.alert("Web-браузер не поддерживает метод createRange");
   }
}
</script>

 

Теперь изменим цвет фона текстового фрагмента, выделенного пользователем:


<p id="txt">Текст для выделения фрагмента</p>
<input type="button" id="btn1" onclick="f_click()" value="Выделить">
<script type="text/javascript">
function f_click() {
   if (document.createRange && window.getSelection) {
      var sel = window.getSelection();
      if (!sel.isCollapsed) {
         var rng = sel.getRangeAt(0);
         sel.collapseToStart(); // Убираем выделение
         // Элемент, в который будем вкладывать выделенный текст
         var s = document.createElement("span");
         s.style.backgroundColor = "#FFE9B3";
         // Вкладываем область в тег span
         rng.surroundContents(s);
      }
      else window.alert("Нет выделенного фрагмента");
   }
   else {
      window.alert("Web-браузер не поддерживает методы");
   }
}
</script>
Комментарии принадлежат их авторам. Мы не несем ответственности за их содержание.
Отправитель Нити