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

Года два назад скриншоты визуального редактора на сайте www.saitistika.ru вызывали восхищение и в то же время недоверие. Каждому, кто хоть немного знаком с HTML, очевидно, насколько ограничены возможности по управлению стандартной формой textarea. И, казалось бы, это единственный инструмент для ввода многострочных текстов в HTML, не считая ActiveX-включений. Однако с распространением Open Source кланов визуального редактора RichEditor оказалось, что разработчиками MS Internet Explorer предусмотрен многофункциональный интерфейс для ввода и правки текстов в пользовательских формах (стабильная работа метода поддерживается в IE версии от 5.0 и выше). И, более того, для включения этого интерфейса достаточно лишь установить одно "волшебное" свойство designMode в значение "on".

И как же это делается? Да очень просто. Мы создаем в HTML-коде страницы редактора объект (для этих целей подойдет конструкция iFrame) и идентифицируем его. Скажем, как newTextArea.

<iframe width="100%" height="100%" id="newTextArea" name="newTextArea"></iframe>

Далее добавляем Java-script-код с одной командой:

<script>
newTextArea.document.designMode = "on";
</script>
 

Попробуйте теперь открыть полученный HTML-файл в IE. Перед нами просторное поле ввода. Вы наверняка сразу же принялись набирать текст. Попробуйте стандартные для Windows команды редактирования (Ctrl-Z - для отката назад, Ctrl-B - для установки стиля выделенного текста в Bold, Ctrl-I для установки стиля в Italic и т.д.). Однако вслед за восторгом от открывающихся перспектив предупреждающим сигналом в сознании звучит: "А как же это использовать практически?!". Для начала нам может понадобиться загрузить в окно редактора какой-либо текст. Это можно сделать стандартной печатью в объект.

newTextArea.document.writeln('Текст');

Хотя, по всем правилам, стоит открыть и закрыть документ объекта

newTextArea.document.open();
newTextArea.document.writeln('Текст');
newTextArea.document.close();

если у вас возникло желание приукрасить текстовое поле. Таким же образом можно направить в объект редактора таблицу стилей (CSS). Но какой смысл вводить или редактировать текст, если нет возможности сохранить изменения?! А сохранить их тоже очень просто. Достаточно создать в начале документа форму, а в ее теле - скрытое поле.

<form name="myform" method="post">
<input type="hidden" name="message">
</form>

Скажем, имя нашей формы будет myform, имя скрытого поля message. Теперь используем это поле как идентификатор. Мы создадим в теле основного документа кнопку, которой назначим событие:

document.myform.message.value = newTextArea.document.body.innerHTML;
myform.submit();

Тем самым мы присваиваем объекту Java-script message содержимое поля ввода редактора на данный момент. И после этого передаем содержимое формы myform на сервер. На стороне сервера мы можем принять содержимое формы посредством сервер-ориентированного языка программирования. Но это уже совсем другая история.

Вам наверняка попадались на глаза буклеты от разработчиков систем управления контентом с заявленной там совместимостью их визуальных редакторов с MS-Word. Желаете заявить то же самое о своем редакторе? Заявляйте смело. Попробуйте открыть в MS-Word какой-либо документ со сложной разметкой. Скопируйте содержимое документа в своей редактор. Удивлены? Документ с большего сохранил свою разметку - и уже в вашем редакторе.

Да и картинки, которые были в исходном документе, тоже перенеслись. Только вот с картинками не все так просто, как хотелось бы. При сохранении документа они потеряются по той простой причине, что редактируемый HTML-документ содержит лишь ссылки на изображения, реально расположенные во временных папках вашего компьютера. Впрочем, первоначальный восторг подпортит еще и тот факт, что MS-Word версии 2000 и выше имеет скверную особенность передавать в буфер документ не в запрошенном HTML-формате, а в формате XHTML, что подразумевает просто безмерное описание каждого мало-мальского фрагмента форматирования документа. В результате XHTML-документ имеет реальный размер, в несколько раз превышающий исходный документ MS-Word. Очевидно, что когда видимые пара страниц текста реально занимают сотню килобайт, мало кто согласится ждать их загрузки с сервера в интернете.

Но все перечисленное на самом деле не проблемы, это - задачи, которые, соответственно, имеют решения. Содержание документа при сохранении мы можем "подчищать". Скажем, в PHP и Perl есть потрясающий механизм для подобного рода действий - функции регулярных выражений preg. Что же касается использования изображений в редактируемом документе, то стоит написать сервисную функцию, которая позволит пользователям самостоятельно добавлять в содержание изображения. Она же позаботится о предварительной загрузке (upload) изображений на сервер.

И если мы уже заговорили о сервисах, то не лишним будет заметить, что отсутствие в нашем редакторе столь привычной для офисных приложений "панели инструментов" вряд ли приведет в восторг пользователей. Так что вместо того, чтобы публиковать на странице редактора список "горячих" клавиш, давайте вообразим себя дизайнерами интерфейса, нарисуем и поместим ожидаемую "панель инструментов". "Кнопкам" этой панели мы самостоятельно назначим наиболее используемые команды форматирования.

Делается это следующим образом. Сначала мы назначаем объекту выделенную в редакторе область текста

var tr = frames.newTextArea.document.selection.createRange();

Далее выполняем над данной областью команду форматирования

tr.execCommand('команда')

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

tr.select();
frames.newTextArea.focus();

Наиболее часто используются команды:

Bold - "жирный" шрифт

Italic - наклонный шрифт

Underline - подчеркивание

JustifyLeft - левое выравнивание

JustifyCenter - центровка по центру

JustifyRight - правое выравнивание

InsertOrderedList - ненумерованный список

InsertUnorderedList - нумерованный список

Undo - откат назад

Redo - откат вперед

Возможны комбинированные команды:

tr.execCommand('FontSize', false, '3');
tr.execCommand('FontName', false, 'Verdana');

Список доступных команд для функции execCommand: msdn.microsoft.com/library/default.asp?url=/workshop/author/dhtml/reference/methods/execCommand.asp

Итак, если собрать рекомендации данной статью воедино, самое меньшее, что мы получим:

<html>
<body>
 <div align=center>
 <script>
  function Post()
   {
    document.myform.message.value = newTextArea.document.body.innerHTML;
    myform.submit();
   }
  function EditorExecCommand(command_param)
   {
    var tr = frames.newTextArea.document.selection.createRange();
    tr.select();
    tr.execCommand(command_param);
    frames.newTextArea.focus();
   }
 </script>
 <form name="myform" method="POST">
 <input type="hidden" name="message">
 </form>
 <input type="button" onClick="EditorExecCommand('Bold');" value=" B ">
 <input type="button" onClick="EditorExecCommand('Italic');" value=" I ">
 <input type="button" onClick="EditorExecCommand('Underline');" value=" U ">
 &nbsp;
 <input type="button" onClick="EditorExecCommand('JustifyLeft');" value=" Left ">
 <input type="button" onClick="EditorExecCommand('JustifyCenter');" value=" Center ">
 &nbsp;
 <input type="button" onClick="EditorExecCommand('InsertOrderedList');" value=" OL ">
 <input type="button" onClick="EditorExecCommand('InsertUnorderedList');" value=" UL ">
 <iframe width="100%" height="80%" id="newTextArea" name="newTextArea"></iframe>
 <input type="button" onClick="Post();" value="Сохранить">
 <script>
  newTextArea.document.designMode = "on";
  newTextArea.document.open();
  newTextArea.document.writeln('Текст');
  newTextArea.document.close();
 </script>
 </div>
</body>
</html>

Теперь вам понадобится толика знаний HTML и Java-script, огромное желание удивить мир, и вы его наверняка удивите. По крайней мере, ваши новоиспеченные гостевые книги наполнятся симпатичными сообщениями благодарных посетителей.

Дмитрий ШЕЙКО,
студия веб-разработок НТЦ "АТЛАС",
sheiko.belsl.com

Версия для печатиВерсия для печати

Номер: 

49 за 2002 год

Рубрика: 

Азбука программирования
Заметили ошибку? Выделите ее мышкой и нажмите Ctrl+Enter!