Глава 14. Пользовательские операции выделения и редактирования



В данной главе рассматривается объект TextRange, который используется для доступа к содержанию документа и манипулирования им. Динамический HTML определяет объектную модель, которая может манипулировать документом с помощью сценариев, аналогично текстовому редактору. Объект TextRange представляет возможности редактирования браузера и операции, которые составляют модель редактирования. Используя объект TextRange, вы можете редактировать любой текст, а также манипулировать текстом, который пользователь выделил на экране.

В данной главе рассмотрены следующие темы:



Введение в объект TextRangeo

Ранее мы рассматривали изменение документа путем прямого манипулирования индивидуальными элементами или таблицами стилей. Как таблицы глобальных стилей манипулируют стилем документа независимо от его структуры, так и объект TextRange манипулирует содержанием документа независимо от стиля и структуры. Данный объект предназначен для добавления внутренних и внешних свойств элементов с целью манипулирования динамическим содержанием, введенным в главе 13. Эти свойства элементов обеспечивают более надежный результат и их следует использовать в общем случае вместо объекта TextRange.

Объект TextRange обеспечивает доступ к тексту, как большому буферу символов.

<HTML>
<BODY>
<H1>Welcome</H1>
<H2>Table of Contents</H2>
<UL>
<LI>Chapter 1</LI>
<LI>Chapter 2</LI>
</UL>
</BODY>
</HTML>

На рис. 14.1 показан текст данного документа, расположенный ниже дерева анализа. Символы, принадлежащие определенному элементу в дереве, находятся в сфере влияния данного элемента. Например, элемент chapter l находится в сфере влияния первого элемента LI.

Рис. 14.1. Отношения между объектом TextRange и структурой документа

Объекты TextRange могут быть созданы только специальными элементами, которые считаются владельцами редактирования текста (text edit owner). Владелец редактирования текста является элементом, который может создать объект TextRange с помощью метода createTextRange, таким образом предоставляя доступ к основному буферу. На данный момент только два типа элементов HTML могут функционировать в качестве владельцев редактирования текста в динамическом HTML: элемент Body является владельцем редактирования текста для всех воспроизводимых элементов, а элементы ввода, такие как Input, Button и TextArea, являются владельцами редактирования текста для своего содержания. Например, вы можете создать объект TextRange для предыдущего документа путем вызова метода createTextRange объекта body:


var tr = document.body.createTextRange();

После создания объекта TextRange можно легко получить доступ к любому элементу содержания внутри объекта.

Первоначально весь текст, находящийся в области влияния владельца текста, содержится в объекте TextRange. Например, объект TextRange в предыдущем документе охватывает весь текст в элементе Body. Вы можете использовать методы объекта TextRange для изменения положения объекта с целью включения в область действия другого текста. Объект TextRange охватывает текст, над которым в данный момент производятся манипуляции или который изменяют. Сценарий может заменить охватываемый текст так же, как пользователь может выделить старый текст и набрать другой текст в текстовом редакторе. Ниже в разделе данной главы "Выполнение команд" вводятся методы манипулирования внешним видом документа, которые аналогичны выбору пользователем шрифта или изменения стиля текста в текстовом редакторе.

Объект TextRange разработан с большой степенью надежности и предназначен для автоматического приема произвольного HTML, внедряемого в документ. Когда новый текст вставляется в объект TextRange, то HTML также вставляется в документ, аналогично тому, как пользователь выбирает команду Paste (Вставить) из меню Edit (Правка) и вставляет произвольный текст. Данные операции являются мощными, но они не предназначены для предоставления разработчику возможности тщательного контроля документа. Напротив, разработчик может использовать данные операции для изменения документа на высоком уровне, не думая о конкретном коде HTML, который реализует данные модификации. Правила управления кодом HTML, которые генерируют данные операции, вероятно, будут изменены в следующей версии браузера Microsoft Internet Explorer. Поэтому объект TextRange не следует использовать, когда результат операции требует, чтобы HTML принимал определенную форму. Вместо него следует использовать внутренние и внешние свойства.



Охватываемый текст

Объект TextRange не определяет текст, который он охватывает, в терминах порядковых индексов символов начала и конца текстовой области. Он определяет содержащийся в нем текст таким образом, при котором данный текст более свободно связан с положением в документе и может отражать изменения состояния документа. Например, если объект TextRange охватывает все содержание документа, а содержание расширяется или сокращается вследствие работы другого процесса, то объект TextRange автоматически отражает данное изменение и продолжает охватывать все содержание документа.


Ограничения объекта TextRange

Объект TextRange в настоящее время очень тесно связан с символами, что обусловливает неясности между объектом TextRange и структурой документа. Во многих случаях в HTML по положению одиночного символа невозможно точно определить HTML-элемент, в области влияния которого находится символ, как показано ниже:

<P>This is <B><I>bold and italic</I> text.</B></P>

В объекте TextRange данное содержание представлено как строка This is bold and italic text. Предком буквы b в текстовом буфере является элемент italic (курсив), а предком элемента italic является элемент Bold (Полужирный). Символы слова "bold" и предшествующий ему пробел не содержат элементов Bold, которые являются их прямыми предками. Используя свойство TextRange, вы не можете вставить выделение полужирным шрифтом, или курсивом перед словом "bold". Объект TextRange на данный момент основан на одиночной точке выделения, которая может находиться перед буквой b (что устанавливает полужирный курсив текста) или в пробеле после слова is (что не устанавливает выделение текста полужирным начертанием и курсивом). Объект TextRange не может вставить текст между тегами <В> и <I>.

Для вставки текста между тегами <В> и <I> используйте методы insertAdjacentText и InsertAdjacentHTML, введенные в главе 13.

Данные методы могут вставить текст перед или после любого открывающего или закрывающего тега в теле документа.



Программирование объекта TextRange

В данном разделе вводятся свойства и методы манипулирования объектом TextRange. Методы позволяют сценариям манипулировать основным текстом почти так же, как пользователь мог бы редактировать его в текстовом редакторе, выделяя текст и вводя или вставляя новый текст в документ.



Создание объекта TextRange

Как упоминалось выше, объект TextRange создается путем вызова метода createTextRange элемента, который является владельцем редактирования текста. Подобно свойствам динамического содержания объект TextRange недоступен до тех пор, пока весь документ не будет проанализирован. В ходе анализа документа попытки создания объекта TextRange при помощи метода createTextRange будут неудачными. Поэтому перед использованием методов, которые возвращают объект TextRange, убедитесь, что документ полностью проанализирован.

Объект TextRange, возвращаемый методом createTextRange, должен быть назначен переменной. В противном случае созданный в памяти объект TextRange будет немедленно разрушен. Ниже показано, как правильно создать Объект TextRange:


var tr = document.body.createTextRange();

Так создавать объект TextRange нельзя:


document.body.createTextRange(); // Этот оператор ничего не делает.

Единственная ситуация, когда не требуется назначать новый объект TextRange переменной, возникает в случае, если последовательность операций может быть выполнена одним действием - например, если вы заменяете HTML, который представлен объектом TextRange:


// Заменяет все содержание тела HTML.
document.body.createTextRange().pasteHTML("<H1>New Document</H1>");


Свойство parentTextEdit

Все элементы имеют свойство parentTextEdit, которое ссылается на владельца редактирования текста, ответственного за содержание элемента. Использование данного свойства может обеспечить коду совместимость с будущими версиями объектной модели. В настоящее время свойства parentTextEdit для большинства элементов в документе ссылаются на элемент Body. Элементы, находящиеся внутри элемента Button, являются единственными исключениями. Владельцем редактирования текста данных элементов является элемент Button. Однако будущие версии объектной модели могут поддерживать большее количество элементов в качестве владельцев редактирования текста. При создании объекта TextRange для элемента следует использовать его свойство parentTextEdit для идентификации владельца редактирования текста, и код должен будет работать даже при смене владельца редактирования текста. Приведенный ниже код иллюстрирует данный метод:


// el представляет объект элемента в документе.
var tr;
if (!el.isTextEdit)
tr = el.parentTextEdit.createTextRange();
else
tr = el.createTextRange();

Каждый элемент в теле документа представляет свойство isTextEdit, которое указывает, является ли элемент владельцем текстового редактирования. Приведенный выше код использует элемент el для создания объекта TextRange, если el является владельцем текстового редактирования. В противном случае код использует владельца редактирования текста предка элемента el. Приведенная ниже строка определяет, что элемент Body является владельцем редактирования текста:


alert(document.body.isTextEdit); // true; элемент Body является
// владельцем редактирования текста.



Представление содержания документа

Объект TextRange содержит свойства text и htmlText, которые обеспечивают доступ к форматированному и неформатированному тексту документа.

Свойство text представляет текст документа без разметки HTML. Это свойство доступно для чтения/записи и может быть использовано для замены неформатированного содержания. Свойство text сходно со свойством outerText объектов элемента тем, как оно представляет содержание документа и типами значений, которые могут быть ему присвоены.

Свойство htmlText представляет текст вместе с разметкой HTML. Данное свойство представляет HTML так же, как свойство outerHTML, но в отличие от свойства outerHTML свойство htmlText доступно только для чтения. Для назначения нового HTML объекту TextRange следует использовать метод pasteHTML. Назначение нового HTML обрабатывается отдельным методом, поскольку не является симметричным при чтении текущего HTML. Значение, которое вы вставляете в текстовую область, используя метод pasteHTML, может не совпадать со значением, которое впоследствии возвращается свойством htmlText. Объект TextRange может изменить или очистить вставляемый HTML, и код HTML может даже повлиять на содержание за границами объекта TextRange.

Метод pasteHTML разработан для вставки действительного HTML. При вызове метода pasteHTML для определенного элемента вставляемый фрагмент будет находиться внутри области действия данного элемента и должен быть действительным кодом HTML внутри данной области действия, в соответствии с определением типа документа (DTD). Браузер попытается удалить недействительный код HTML и может расширить HTML за границы, исходно установленные объектом TextRange. При возвращении метода pasteHTML объект TextRange обновляется, чтобы включить вставленный текст в свою область действия.


Сравнение свойств text и htmlText

Главное преимущество использования свойства text по сравнению с htmlText и pasteHTML заключается в обработке компонентов, представляющих угловые скобки. Когда вы присваиваете значение свойству text, это значение анализируется как неформатированный HTML, так что угловые скобки автоматически заменяются на соответствующие компоненты. Например, <is заменяется на &lt;. При чтении свойства text компоненты возвращаются в виде буквенных значений.

При вставке нового текста в текстовую область с помощью метода pasteHTML текст анализируется как код HTML, поэтому любые угловые скобки интерпретируются как часть тегов HTML. Если необходимо вставить угловую скобку в текст, то вы должны заменить соответствующий компонент вручную. Когда вы используете свойство htmlText для извлечения текстовой области, то все угловые скобки в тексте представлены в виде компонентов. Например, <is возвращается как &lt;.


Пробел

Свойство text объекта TextRange представляет пробел так, как он воспроизводится на экране, а не в основном документе. В большинстве случаев в HTML дополнительные пробелы игнорируются. Например, если HTML-документ использует три пробела между словами, то текст будет отображаться с одним пробелом между каждым словом. Кроме того, возвраты каретки внутри HTML-документа игнорируются. Теги блока определяют разрывы строки.

Исключением из данных правил являются элементы PRE и ХМР, в которых существующие пробелы сохраняются и поддерживаются любые пробелы, которые будут вставлены позднее.


Плавающие закрывающие теги

Нельзя закрыть элемент в документе до закрывающего тега. Предположим, что в документе находится элемент Bold:

<B>This is bold text.</B>

Если объект TextRange используется для вставки нового закрывающего тега между словами bold и text, то новый тег не станет закрывающим тегом для элемента Bold.

Метод pasteHTML не вставляет фрагмент в дерево. Фрагмент проверяется на соответствие DTD, которое определяет, что дополнительные закрывающие теги будут игнорироваться. Поэтому вставка тега не окажет влияния на текст или дерево документа.


Недействительная область действия

Некоторые HTML-элементы могут быть действительными только внутри области действия других элементов. Например, считается, что элемент TD находится в элементе TR внутри таблицы Table. В главе 7 описываются правила анализатора для обработки элементов в исходном документе, которые не находятся внутри действительной области действия. Многие правила также применимы к HTML, который вставляется с помощью объекта TextRange. Например, приведенный ниже код пытается заменить тело документа на один элемент TD:


var tr = document.body.createTextRange();
tr.pasteHTML("<TD>Cell outside any table or row</TD>");

В данном примере содержание вставляется в документ, но окружающие теги <TD> игнорируются, поскольку не определена действительная таблица. Нет гарантии, что обработка этой ошибки будет поддержана в последующих версиях динамического HTML. Поэтому для получения предсказуемых результатов следует вводить действительный фрагмент HTML.



Связь объекта TextRange со структурой документа

Метод parentElelment объекта TextRange сообщает об отношениях между текстовой областью и структурой документа. Данный метод возвращает последний элемент в дереве анализа, который влияет на всю область текста. Как показано на рис. 14.1, на каждый символ в текстовой области влияет конечный узел (leaf node, узел без дочерних элементов). Когда объект TextRange представляет символ, то его метод parentElement возвращает конечный узел, влияющий на символ. Когда объект TextRange представляет область символов, то его метод parentElement является узлом, который воздействует на всю область. Когда объект TextRange сначала создается для элемента Body, то он представляет весь текст, так что его метод parentElement является обычно самим элементом Body.



Позиционирование объекта TextRange

Изначально объект TextRange заключает в себе весь текст, который находится в области влияния владельца редактирования текста, в котором он был создан. Например, вызов метода createTextRange элемента Body возвращает текстовую область, которая включает все содержание тела.

Набор методов объекта TextRange изменяет положение объекта TextRange для охвата различного текста. Основная архитектура объекта TextRange не связана с порядковыми индексами символов, которые он охватывает в текстовом буфере. Нельзя непосредственно манипулировать конечными точками текстовой области, назначая их новым символьным индексам. Вместо этого методы перемещения объекта TextRange изменяют положение объекта для осуществления операций с текстом. Они могут позиционировать объект TextRange для охвата всех символов, слов, предложений, владельца редактирования текста, элемента или точки на экране. Данные методы не приводят к перемещению текста по документу. Ниже перечислены методы позиционирования объекта TextRange:

Для изменения положения объекта TextRange предназначены методы setEndPoint и moveToBookniark. Метод setEndPoint дополняет метод compareEndPoints.

Эти методы обсуждаются ниже в разделах данной главы "Управление объектами TextRange" и "Манипулирование закладками".


Методы expand и collapse

Метод expand расширяет объект TextRange для полного охвата символа, слова, предложения или всего текста владельца редактирования текста, в котором он был создан. Например, если объект TextRange охватывает часть слова, вызов его метода expand с параметром word приводит к распространению метода на все слово. В случае успеха метод expand возвращает true.

Метод collapse выполняет обратную операцию, помещая открывающие и закрывающие маркеры объекта TextRange вместе в качестве точки вставки. Необязательный параметр определяет, будет ли помещена точка вставки в начале или конце текущей области. Значение по умолчанию равно true, что приводит к установке точки вставки в начало.


Метод moveToElementText

Метод moveToElement размещает объект TextRange для охвата текста, находящегося в области действия данного элемента. Несмотря на согласованность данного метода с поведением объекта TextRange нет гарантии, что присвоение значения объекту TextRange, размещенному с использованием moveToElementText, приведет к изменению только содержания элемента. Если требуется прямо изменить содержание элемента, то следует использовать внутренние и внешние свойства, введенные в главе 13.

Метод moveToElementText применяется для перемещения по документу с целью выполнения последующих манипуляций, например, анализа первого слова всех заголовков. Объект TextRange может быть легко перемещен в элемент без анализа строк кода. В следующем разделе рассматриваются некоторые методы выполнения этой задачи.


Методы move, moveStart u moveEnd

Методы move, moveStart и moveEnd перемещают объект TextRange на определенное расстояние. Методы moveStart и moveEnd изменяют положение открывающих и закрывающих маркеров объекта TextRange. Метод move перемещает открывающий маркер объекта TextRange на определенное расстояние и сжимает объект до точки вставки.

Все три метода принимают два одинаковых параметра. Первый параметр определяет необходимость перемещения слова, символа или предложения в конец текстового потока. Второй параметр определяет расстояние перемещения. Второй параметр может иметь положительное или отрицательное значение, что указывает направление перемещения: вперед или назад. Первый параметр может иметь одно из перечисленных в табл. 14.1 значений:

Таблица 14.1. Значения первого параметра методов move, moveStart и moveEnd


Единица Определение

character Перемещает на определенное число символов
word Перемещает на определенное число слов
sentence Перемещает на определенное число предложений
textedit Перемещает на определенное число элементов редактирования текста

Методы move, moveStart и moveEnd возвращают число, равное расстоянию перемещения. Например, если вы пытаетесь переместить 200 слов в документе, содержащем 100 слов, то метод move поместит объект TextRange в последнее слово в данном документе и возвратит число перемещенных слов. Для проверки успешности проведения операции сравните возвращаемое значение с числом перемещенных слов:


if (200 == tr.move("word", 200)) {
// Успешно!
}
else { // Невозможно переместить 200 слов.
}

Метод move помещает объект TextRange как точку вставки между двумя символами. Например, вызов метода move для перемещения вперед трех слов помещает объект TextRange между третьим и четвертым словами. В данном случае свойство text вернет пустую строку. Присвоение значения свойству text или вызов метода pasteHTML приведет к вставке текста в данную точку документа.

Методы moveStart и moveEnd изменяют положение открывающего и закрывающего символов. Например, данный метод может быть использован для расширения выделения с четырех до пяти слов, путем перемещения исходной позиции вперед или конечной позиции назад. Приведенный ниже фрагмент кода демонстрирует получение первого слова элемента в документе:


function firstWord(myElement) {
// Obtain a TextRange object.
var tr = document.body.createTextRange();
// Перемещает объект TextRange.
// myElement представляет элемент в документе.
tr.moveToElementText(myElement);
// Сворачивает объект TextRange к началу элемента.
tr.collapse();
if (tr.moveEnd("word", 1))
return tr.text;
else
return "";
}

Следующий пример демонстрирует подсчет числа слов в документе. Данный код может быть легко изменен для подсчета других единиц путем изменения первого параметра в методе move.


function countWords() {
var tr = document.body.createTextRange();
var intCount = 0;
// Сворачивает объект TextRange к началу документа.
tr.collapse(true);
while (tr.move("word", 1)) intCount++;
return intCount;
}

При перемещении слова или символов все элементы, представляющие объект, включая изображения, внутренние элементы управления и так далее, являются одной единицей.

Примечание: Способы перемещения объекта TextRange, которые применяются в данных методах, можно сравнить со способами перемещения или изменения выделения текста с помощью сочетания клавиш в популярных текстовых процессорах, таких как Microsoft Word. Например, метод move изменяет положение объекта TextRange как точки вставки, аналогично изменению положения курсора в текстовом процессоре с помощью клавиш со стрелками <Right> и <Left>. Нажатие клавиши со стрелкой перемещает курсор на один символ. Нажатие клавиши со стрелкой при нажатой клавише <Ctrl> перемещает курсор на одно слово. Методы moveStart и moveEnd разворачивают или сворачивают текст, охватываемый объектом TextRange, аналогично тому, как с помощью сочетания клавиш изменяется размер области выделенного текста. Нажатие клавиши со стрелкой <Right> или <Left> при нажатой клавише <Shift> приводит к расширению или сужению области выделения на один символ в выбранном направлении. Удерживание нажатыми клавиш <Shift> и <Ctrl> приводит к изменению области выделения на одно слово одновременно.


Метод moveToPoint

Метод moveToPoint принимает в качестве аргумента точку в клиентской области на экране, определяет элемент, который будет выведен на экран в данной точке и помещает объект TextRange в качестве точки вставки данного элемента. Этот метод при использовании в обработчике событий мыши для определения области текста, над которой находится указатель мыши, обеспечивает большую точность, чем свойство srcElement, которое возвращает элемент, на котором находится указатель мыши. Приведенный ниже код обработчика событий мыши отображает в строке состояния слово, над которым находится указатель мыши:


function doMouseMove() {
var tr = document.body.createTextRange();
tr.moveToPoint(event.clientX, event.clientY);
// Охватывает все слово, над которым находится указатель мыши.
tr.expand("word");
window.status = tr.text;
}
document.onmousemove = doMouseMove;


Метод findText

Метод findText осуществляет поиск выбранной строки в документе. Диалоговые окна Find (Найти) браузера используют метод findText и могут продемонстрировать гибкость данного метода.

Метод findText использует три параметра. Первый параметр представляет строку, которую требуется найти в документе. Второй параметр представляет число символов, которые следует искать в документе. Значение должно быть положительным для поиска в прямом направлении или отрицательным для поиска в обратном направлении. Третий параметр определяет, должно ли совпадать слово целиком и следует ли учитывать регистр: значение 2 задает совпадение слова целиком, 4 - учитывает регистр и 6 - устанавливает оба параметра.



Управление объектами TextRange

Существуют методы для клонирования объекта TextRange, сравнения двух объектов TextRange и для позиционирования одного объекта TextRange относительно другого.


Метод duplicate

Метод duplicate создает копию объекта TextRange, из которого он был вызван. Например, приведенный ниже фрагмент кода создает копию объекта TextRange с именем tr:


var tr2 = tr.duplicate();


Методы inRange и isEqual

Метод inRange определяет, находится ли указанная текстовая область внутри области действия объекта TextRange, из которого был вызван данный метод:


alert(tr2.inRange(tr)); // true; tr находится внутри tr2.

Метод isEqual сравнивает два объекта TextRange и определяет, охватывают ли они один и тот же текст. Метод необходим, потому что объекты TextRange, представляющие одну текстовую область, могут быть, тем не менее, различными объектами, так что прямое их сравнение не будет работать. Приведенный ниже код демонстрирует правильный и неправильный способ проверки, охватывают ли два объекта один текст:


// Установка примера.
var tr = document.body.createTextRange();
var tr2 = tr.duplicate();
// Неправильный способ сравнения текстовых областей:
alert(tr == tr2); // false; данные два объекта различны. // Правильный способ сравнения текстовых областей:
alert(tr.isEqual(tr2)); // true


Методы compareEndPoints и setEndPoint

Метод compareEndPoints сравнивает два объекта TextRange и выясняет, совпадают ли их начальные и конечные позиции. Метод setEndPoint устанавливает начальную и конечную позиции объекта TextRange в начальную и конечную позиции другого объекта TextRange. Оба метода принимают два параметра. Начальная и конечная позиции объекта TextRange, из которого был вызван метод, сравниваются или устанавливаются в начальные и конечные позиции объекта TextRange, который определен во втором параметре. Первый параметр может быть равен любому значению в табл. 14.2, которое определяет используемые положения.

Таблица 14.2. Значения первого параметра методов compareEndPoints и setEndPoint


Значение Описание

StartToStart Устанавливает или сравнивает начальную позицию текущего объекта TextRange с начальной позицией объекта TextRange, определенного во втором параметре
StartToEnd Устанавливает или сравнивает начальную позицию текущего объекта TextRange с конечной позицией объекта TextRange, определенного во втором параметре
EndToEnd Устанавливает или сравнивает конечную позицию текущего объекта TextRange с конечной позицией объекта TextRange, определенного во втором параметре
EndToStart Устанавливает или сравнивает конечную позицию текущего объекта TextRange с начальной позицией объекта TextRange, определенного во втором параметре

Приведенная ниже функция определяет, будет ли продолжен объект trDest после окончания объекта trSrc:


function continues(trSrc, trDest) {
return trSrc.compareEndPoints("EndToStart", trDest);
}


Прокручивание области просмотра

Обработка объектов TextRange производится целиком в памяти. Изменение свойств text и htmlText в объекте TextRange не приводит к прокручиванию документа. Для прокручивания текста, охватываемого объектом TextRange, следует использовать метод scrollIntoView, который поддерживают все элементы. Для данного метода должен быть указан одиночный необязательный параметр, который определяет необходимость прокручивания текста в объекте TextRange в верхнюю (значение true) или нижнюю (значение false) часть экрана.



Манипулирование закладками

Закладка определяет положение объекта TextRange в тексте, аналогично закладке HTML, которая определяет местоположение в документе. Вы можете использовать метод getBookmark объекта TextRange для сохранения записи текущего положения объекта как закладки, а его метод moveToBookmark - для возвращения сохраненного положения.

Метод getBookmark возвращает закладку как строковое значение. Подобно объекту TextRange закладка не фиксирует начальное и конечное положение как символьные индексы. Закладка представляет собой строку, которая содержит информацию о положении в зашифрованной форме. Данной строкой нельзя манипулировать напрямую и ее следует использовать только с методами TextRange.

Метод moveToBookmark принимает строку закладки как параметр и располагает объект TextRange в соответствии с закладкой. Данный метод возвращает логическое значение, которое указывает успешность проведенной операции.

Можно обеспечить совпадение положений двух объектов TextRange путем вызова метода первого объекта moveToBookmark и передачи ему закладки, возвращенной методом getBookmark второго объекта. Однако для копирования закладки проще использовать метод duplicate.



Внедренные объекты

Внедренные объекты представляют собой HTML-элементы, которые являются внутренними элементами управления, элементами Object, изображениями и так далее. Каждый внедренный объект представлен пробелом в объекте TextRange. Чтобы определить, представляет ли пробел в объекте TextRange внедренный объект, используйте другой объект TextRange, который охватывает только пробел и примените метод parentElement.

Для добавления внедренного объекта в объект TextRange вставьте соответствующий HTML в документ, используя метод pasteHTML. После выполнения назначения и анализа HTML, текст в объекте TextRange автоматически обновляется с учетом пробела для представления вновь подтвержденного внедренного объекта.



Выбор текстовой области

Метод select объекта TextRange выделяет выбранный пользователем текст, находящийся в области действия данного объекта. Когда выбран объект TextRange, охватываемый им текст выделен на экране. Последующее расширение области действия объекта TextRange не приводит к расширению области выделения, если только вы не вызвали метод select снова.



Доступ к выделенной пользователем области

Операция выделения пользователем текста непосредственно связана с объектом TextRange. Свойство selection документа используется для ссылки из сценария на объект, который представляет текущее выделение в браузере. Данный объект selection также представляет свойство type, которое возвращает тип выбора: None при отсутствии выбора и Text для выделения текста. Когда текст выделяется на экране, то метод createRange объекта выделения возвращает объект TextRange, который охватывает выбранный текст. Перемещение данного объекта TextRange не приведет к изменению области выделенного текста, но изменения в тексте, произведенные объектом TextRange, безусловно, будут отражены на экране. Чтобы привести область выделения на экране в соответствии с объектом TextRange, можно вызвать метод select объекта TextRange. Например, приведенный ниже код использует объект TextRange для расширения об-ласти выделения на экране на одно слово:


if ("Text" == document.selection.type) {
var tr = document.selection.createRange();
// Переместить конечную позицию для включения // одного дополнительного слова.
tr.moveEnd("word", 1);
// Снятие выделения области.
tr.select();
}
else alert("No text is selected.");

Всегда следует проверять тип выделения перед выполнением каких-либо манипуляций, потому что браузер поддерживает второй тип объекта, с именем ControlRange для выбора многочисленных элементов управления. Поскольку на данный момент невозможно выделить многочисленные элементы управления во время просмотра документа, то объект ControlObject не обсуждается.



Выполнение команд

Объектная модель динамического HTML представляет набор методов, которые позволяют непосредственно выполнять пользовательские операции в области или документе. Данные операции соответствуют различным действиям, которые пользователь может выполнять с текстом. Например, имеются команды для выделения или снятия выделения текста полужирным начертанием, аналогично кнопке переключения Bold (Полужирный) в текстовом редакторе. Эти команды изменяют основной HTML для достижения требуемого результата. На данный момент все манипуляции стилем обеспечиваются внедрением разметки HTML в документ. При этом не гарантируется, что команды будут выполнять манипуляции стилем в будущих версиях браузеров так же. Единственное, что можно гарантировать - видимый результат действия команд будет одинаков.

Данные команды позволяют странице манипулировать стилем и содержанием документа, не заботясь о структурных правилах HTML. Например, при вызове команды Bold генерируется соответствующий код HTML. Также поддерживаются команды для выполнения других базовых пользовательских операций, таких как вырезание и копирование текста, добавление элементов управления в фиксированные области и отмена последней операции.

Объекты TextRange и объект document представляют ряд методов для выполнения и создания запроса состояния команд. Данные методы разделены на две категории: методы, которые возвращают состояние команды, и методы, которые выполняют команду. Для определения состояния команды доступны шесть методов, которые перечислены ниже:

Данные методы более понятны в контексте пользовательского интерфейса текстового редактора. Методы queryCommandSupported и queryCommandEnabled возвращают логические значения, сообщая о поддержке и доступности выбранной команды. Если команда отключена, то ее выполнение не оказывает никакого влияния на документ. Метод queryCommandState определяет, будет ли указанная команда выполнена на объекте. Например, вызов данного метода с параметром Bold возвращает true, если объект охватывает текст с полужирным начертанием, false в противном случае и null, если метод не может определить состояние. Метод queryCommandIndeterm проверяет доступность состояния команды. Например, если объект TextRange охватывает полужирный и обычный текст, то данный метод возвращает true, поскольку действительное полужирное состояние недоступно.

Методы queryCommandText и queryCommandValue обеспечивают дальнейшую информацию о команде. Метод queryCommandText возвращает короткую строку меню или более длинную строку состояния, которая описывает функцию. Поскольку текст в этих строках может изменяться в различных браузерах, следует написать код, который не полагается на определенную возвращаемую строку. Метод queryCommandValue возвращает реальное значение команды. Например, вызов данного метода с параметром FontName возвращает имя шрифта.

Приведенные выше методы не оказывают влияния на документ. Они просто возвращают информацию о текущем состоянии. Для взаимодействия с документом представлены перечисленные ниже методы:

Метод execCommand выполняет команду. Аргумент cmdID представляет необходимую команду, которая должна быть вызвана. Необязательный параметр displayUI определяет необходимость отображения или скрытия соответствующего пользовательского интерфейса. По умолчанию связанный пользовательский интерфейс не отображается. В некоторых случаях обход пользовательского интерфейса потенциально опасен. Поэтому аргумент displayUI игнорируется и всегда отображается пользовательский интерфейс. Например, перед выполнением команды Print (Печать) будет выведено окно с сообщением для пользователя. Атрибут value указывает значение для команды. Метод execCommandShowHelp отображает файл справки, если он поддерживается для определенной команды.

Приведенный ниже код, который анализирует документ для определения числа отображаемых шрифтов, иллюстрирует использование метода queryCommandValue:


<SCRIPT LANGUAGE="JavaScript">
function walkDocument() {
var fonts = new Array();
var tr = document.body.createTextRange();
tr.collapse();
while (tr.moveEnd("character", 1)) {
var val = tr.queryCommandValue("FontName");
if (null == fonts[val]) {
fonts[val] = true;
fonts.length++
}
tr.collapse(false);
}
var settings = "Total Fonts: " + fonts.length + "\n";
for (var font in fonts) {
settings += " " + font + "\n";
}
alert(settings);
}
</SCRIPT>

На прилагаемом компакт-диске находится список всех доступных команд и типов значений, которые они принимают и возвращают.