КулЛиб - Классная библиотека! Скачать книги бесплатно 

JavaScript. Визуальные редакторы : учебное пособие для СПО [Валерий Викторович Янцев] (pdf) читать онлайн

Книга в формате pdf! Изображения и текст могут не отображаться!


 [Настройки текста]  [Cбросить фильтры]
В. В. ЯНЦЕВ

JAVASCRIPT
ВИЗУАЛЬНЫЕ
РЕДАКТОРЫ
Учебное пособие

•САНКТПЕТЕРБУРГ•МОСКВА•КРАСНОДАР•
•2022•

УДК 004
ББК 32.97я723
Я 65

Янцев В. В. JavaScript. Визуальные редакторы : учебное пособие
для СПО / В. В. Янцев. — СанктПетербург : Лань, 2022. — 168 с. :
ил. — Текст : непосредственный.

ISBN 9785811489435
Подавляющее большинство ныне действующих сайтов сделано при
помощи CMS. А такие системы невозможно представить без визуальных
редакторов страниц. WYSIWYGредакторы позволяют администратору
управлять содержимым ресурса, не будучи знакомым даже с азами про
граммирования.
Многие разработчики используют не готовые CMS, а пишут собст
венные. Данная книга призвана помочь им в этом непростом деле. На ее
страницах описаны четыре WYSIWYGредактора — на разный вкус и для
разных задач. Все системы являются оригинальными и не содержат каких
либо заимствований кода. Функциональные возможности приведенных
разработок имеют исчерпывающие описания и разъяснения.
Разобранные в книге визуальные редакторы могут быть интегрированы
в уже существующую CMS или работать напрямую с сайтом без сопут
ствующих инструментов. Особо надо отметить, что эти редакторы позволяют
администратору сайта видеть, как будет выглядеть страница еще до того,
как он запишет внесенные изменения в файл или базу данных.
Книга имеет сайт поддержки, где читатель может ознакомиться с
редакторами и опробовать их в действии. Кроме того, вы можете скачать
zipархив со всеми файлами и запустить их на своем компьютере. Для этого
книга содержит подробные инструкции по созданию локального хостинга
на ПК.
Соответствует современным требованиям Федерального государствен
ного образовательного стандарта среднего профессионального образования
и профессиональным квалификационным требованиям.
Рекомендовано в качестве дополнительной литературы для студентов,
обучающихся в средних профессиональных учебных заведениях по направ
лению «Информатика и вычислительная техника».

УДК 004
ББК 32.97я723

Обложка
П. И. ПОЛЯКОВА

© Издательство «Лань», 2022
© В. В. Янцев, 2022
© Издательство «Лань»,
художественное оформление, 2022

ОГЛАВЛЕНИЕ
1. Введение ................................................................................................................... 7
1.1. О чем эта книга.................................................................................................. 7
1.2. Особенности изложения материала ................................................................ 8
1.3. Оформление сценариев .................................................................................... 9
2. Прежде чем начать ................................................................................................ 10
2.1. CMS .................................................................................................................. 10
2.2. WYSIWYG ....................................................................................................... 11
2.3. Атрибут contentEditable .................................................................................. 11
2.4. Свойство designMode...................................................................................... 12
2.5. Метод getSelection ........................................................................................... 13
2.6. Отменен ли execCommand?............................................................................ 13
2.7. Методы createElement и surroundContents .................................................... 15
2.8. Что и как мы напишем.................................................................................... 15
3. Среда разработки ................................................................................................... 18
3.1. Выясняем разрядность ОС ............................................................................. 19
3.2. Установка пакета Visual C++ ......................................................................... 20
3.3. Установка сервера Apache 2.4 ....................................................................... 22
3.4. Установка PHP 8 ............................................................................................. 28
3.5. Установка редактора Notepad++ 8 ................................................................ 31
4. Тестирование программ ........................................................................................ 37
4.1. Тестирование сайта и редакторов в браузерах ............................................ 37
4.2. Тестирование сайта и редакторов в валидаторах ........................................ 39
4.3. Проверка работы сайта и редакторов в консоли ......................................... 42
5. Структура проекта ................................................................................................. 44
5.1. Состав zip-архива ............................................................................................ 44
5.2. Сайт .................................................................................................................. 45
5.3. Редакторы ........................................................................................................ 46
6. Сборка демонстрационного сайта ....................................................................... 47
6.1. Пишем заготовку............................................................................................. 47
6.2. Файл таблицы стилей ..................................................................................... 51
6.3. Файл со сценариями ....................................................................................... 52
6.4. Дизайн сайта .................................................................................................... 54
6.5. Выделяем редактируемую область ............................................................... 55
6.6. Подключаем PHP ............................................................................................ 55
7. Структура редакторов ........................................................................................... 58
7.1. Пишем заготовку............................................................................................. 58
7.2. Файл таблицы стилей ..................................................................................... 60
7.3. Файл со сценариями ....................................................................................... 61
7.4. Добавляем фрейм для просмотра страницы ................................................ 61
7.5. Дизайн редакторов .......................................................................................... 62
7.6. Подключаем PHP ............................................................................................ 63

3

8. Базовые компоненты редакторов......................................................................... 66
8.1. WYSIWYG и текстовый режимы .................................................................. 66
8.2. Главная панель ................................................................................................ 68
8.3. Кнопки простого редактирования ................................................................. 75
8.4. Блок настроек линий....................................................................................... 77
8.5. Блок настроек таблиц ..................................................................................... 80
8.6. Блок настроек рисунков ................................................................................. 81
8.7. Блок настроек фреймов .................................................................................. 84
8.8. Блок выбора символов .................................................................................... 86
8.9. Блок настроек ссылок ..................................................................................... 87
8.10. Блок настроек заголовков ............................................................................ 90
8.11. Блок настроек выравнивания текста в абзацах .......................................... 91
8.12. Блок настроек шрифтов ................................................................................ 92
8.13. Блок настроек цвета текста .......................................................................... 93
8.14. Удаление форматирования и ссылки .......................................................... 94
9. Общие фрагменты сценариев ............................................................................... 96
9.1. Регистрация «главного» обработчика ........................................................... 96
9.2. Выбор загружаемой страницы ....................................................................... 97
9.3. Взаимодействие области контента, WYSIWYG
и текстового редакторов ........................................................................................ 98
9.4. Фиксация в памяти выделенного фрагмента ............................................. 102
9.5. Открытие и закрытие вкладок с настройками ........................................... 102
9.6. Выбор рисунка .............................................................................................. 104
9.7. Навигация по внесенным изменениям........................................................ 105
9.8. Запись отредактированной страницы ......................................................... 109
10. Традиционный редактор ................................................................................... 111
10.1. Включение режима редактирования ......................................................... 111
10.2. Копирование текста .................................................................................... 112
10.3. Удаление форматирования и ссылок ........................................................ 112
10.4. Простое редактирование текста ................................................................ 113
10.5. Изменение цвета букв или фона текста .................................................... 114
10.6. Добавление разметки маркированного списка ........................................ 115
10.7. Вставка линии ............................................................................................. 117
10.8. Вставка фрейма ........................................................................................... 119
10.9. Вставка рисунка .......................................................................................... 120
10.10. Вставка таблицы ....................................................................................... 121
10.11. Вставка символов ...................................................................................... 123
10.12. Добавление ссылки ................................................................................... 124
10.13. Добавление заголовка ............................................................................... 125
10.14. Выравнивание абзаца ............................................................................... 127
10.15. Настройка шрифта .................................................................................... 127
11. Редактор с фиксированными стилями ............................................................ 129
11.1. Установка режима редактирования .......................................................... 130
11.2. Копирование текста .................................................................................... 130
11.3. Удаление форматирования и ссылок ........................................................ 131
4

11.4. Простое редактирование текста ................................................................ 131
11.5. Изменение цвета букв или фона текста .................................................... 131
11.6. Добавление разметки маркированного списка ........................................ 132
11.7. Вставка линии ............................................................................................. 133
11.8. Вставка фрейма ........................................................................................... 133
11.9. Вставка рисунка .......................................................................................... 134
11.10. Вставка таблицы ....................................................................................... 134
11.11. Вставка символов ...................................................................................... 135
11.12. Добавление ссылки ................................................................................... 135
11.13. Добавление заголовка ............................................................................... 136
11.14. Выравнивание абзаца ............................................................................... 136
11.15. Настройка шрифта .................................................................................... 137
12. Креативный редактор ........................................................................................ 138
12.1. Файлы редактора и сайта ........................................................................... 141
12.2. Включение режима редактирования ......................................................... 144
12.3. Открытие и закрытие HTML-редактора ................................................... 144
12.4. Взаимодействие HTML-редактора и области контента .......................... 146
12.5. Копирование текста .................................................................................... 146
12.6. Удаление форматирования и ссылок ........................................................ 146
12.7. Простое редактирование текста ................................................................ 146
12.8. Изменение цвета букв или фона текста .................................................... 146
12.9. Добавление разметки маркированного списка ........................................ 147
12.10. Вставка линии ........................................................................................... 147
12.11. Вставка фрейма ......................................................................................... 147
12.12. Вставка рисунка ........................................................................................ 147
12.13. Вставка таблицы ....................................................................................... 147
12.14. Вставка символов ...................................................................................... 148
12.15. Добавление ссылки ................................................................................... 148
12.16. Добавление заголовка ............................................................................... 148
12.17. Выравнивание абзаца ............................................................................... 148
12.18. Настройка шрифта .................................................................................... 148
12.19. Перемещение панели ................................................................................ 148
13. Ретро-редактор ................................................................................................... 152
13.1. Установка режима редактирования .......................................................... 152
13.2. Простое редактирование текста ................................................................ 153
13.3. Изменение цвета букв или фона текста .................................................... 155
13.4. Вставка линии ............................................................................................. 155
13.5. Вставка фрейма ........................................................................................... 156
13.6. Вставка рисунка .......................................................................................... 157
13.7. Вставка таблицы ......................................................................................... 157
13.8. Вставка символов ........................................................................................ 158
13.9. Добавление ссылки ..................................................................................... 158
13.10. Добавление заголовка ............................................................................... 159
13.11. Выравнивание абзаца ............................................................................... 159
13.12. Настройка шрифта .................................................................................... 159
5

14. Файл записи данных.......................................................................................... 160
14.1. Заглушка ...................................................................................................... 160
14.2. Рабочий файл ............................................................................................... 160
15. Подведем итоги ................................................................................................. 164

6

1. Введение
Автор начал заниматься программированием в 2003 году. С 2004 года за
довольно короткий промежуток времени успел поработать в нескольких
студиях web-дизайна и вот на что обратил внимание: в те годы почти каждая
такая студия, большая или маленькая, старалась написать собственные
«движки» для сайтов, или, иначе говоря, CMS. Получались они очень
разными — от весьма простеньких и неказистых до серьезных профессиональных разработок.
Не остался в стороне от этой моды и автор, только написал такую систему
не во взаимодействии с группой программистов и дизайнеров, а полностью
самостоятельно. Называлась она непритязательно — СОУС (Система оперативного управления сайтом). Естественно, автор постоянно ее совершенствовал,
наращивал функциональные возможности и т. д. До 2016 года я и многие мои
клиенты вполне успешно пользовались данной разработкой.
Однако в это время происходили два важных процесса:
– зарождение HTML 5;
– появление на рынке большого числа мощных CMS.
Наступил момент, когда автор уже не мог в одиночку конкурировать с
такими проектами, как WordPress, Joomla, Drupal, 1С-Битрикс и другими.
Кроме того, замена ингредиентов СОУСа с HTML 4 на HTML 5 требовала
немалых усилий.
В итоге СОУС был отправлен в архив, после чего автор занялся другими
разработками, но по-прежнему интересовался тем, что происходит в индустрии
создания «движков». А самое главное, продолжал заниматься написанием
WYSIWYG-редакторов, которые являются составными частями любых CMS.
Таким образом, на сегодняшний день у меня накопился немалый опыт
создания самых разных визуальных редакторов для самых разных webпроектов. Этим опытом я и хочу поделиться на страницах данной книги.
1.1. О чем эта книга
Книг о синтаксисе языка программирования JavaScript много. Я бы даже
сказал, очень много. Конечно, каждая из них по-своему хороша, интересна и
полезна, но в конечном счете все они об одном и том же.
Есть ряд книг, в которых излагаются не только основы языка, но и даются
примеры сценариев. Они могут объяснить начинающему разработчику, каким
образом создаются реальные проекты.
Но изданий, рассказывающих о такой популярной среди программистов
теме, как создание CMS, и, более конкретно, о создании WYSIWYG-редакторов,
практически нет. Из известных мне книг по JavaScript лишь в двух упоминается
о существовании таких редакторов и лишь в одной (изданной много лет тому
назад) рассматривается довольно элементарный пример. Частично я попытался
осветить этот вопрос в своем учебнике «JavaScript. Готовые программы». Но и
7

там, несмотря на описание нескольких очень простых разработок, информация
по теме была крайне незначительна.
Как уже понятно из сказанного выше, эта книга познакомит читателя с
процессом создания профессиональных визуальных редакторов. Причем не
одного, а сразу нескольких. Если быть точнее — четырех. Вы узнаете, как
разработать сайт с контентом, который может редактироваться онлайн. Узнаете,
как выглядит структура типичного WYSIWYG-редактора, как с помощью
такого редактора можно написать web-страницу и по мере необходимости
вносить изменения в текст, добавлять изображения, таблицы, линии, символы и
многое другое.
Но это будут не просто теоретические рассуждения. Если в книге
представлены лишь фрагменты кода, то, скачав по ссылке https://
editjs.ru/EDIT.zip zip-архив, вы получите в свое распоряжение весь проект,
включая демонстрационный сайт, 4 редактора, файлы сценариев и таблиц
стилей, а также весь контент, использованный в данной системе.
И это еще не все. Вы можете заглянуть на демонстрационный сайт
проекта https://editjs.ru/ и проверить в действии и сайт, и редакторы.
Единственное, на что необходимо обратить внимание: в демонстрационных
редакторах функции записи изменений в контенте отключены. Сделано это для
того, чтобы избавить особо пытливые умы от соблазна оставить после себя на
сайте что-нибудь непотребное.
Наконец, еще один важный момент. Как понятно из названия книги,
главное действующее лицо в ней — язык программирования JavaScript. 90%
кода любого из редакторов — на JavaScript. Поэтому было бы неплохо, если бы
читатели оказались знакомы с основами и синтаксисом этого языка.
1.2. Особенности изложения материала
В книге четырнадцать глав.
Первая — «Введение». Вы сейчас читаете ее.
Во второй мы познакомимся с «фундаментом», на котором построены
«здания» редакторов, а также подробнее разберем, что же все-таки нам
предстоит написать.
Третья глава посвящена созданию среды разработки на персональном
компьютере. Если вы хотите скачать zip-архив и экспериментировать на своем
ПК, необходимо создать на нем локальный хостинг, установив несколько
программ.
Из главы 4 вы узнаете, как проверялись и тестировались файлы нашего
проекта.
Глава 5 познакомит вас со структурой проекта и составом zip-архива.
В шестой мы подробно разберем, как создать демонстрационный сайт и
выделить в контенте редактируемую область.
В седьмой рассмотрим структуру редакторов.
Название восьмой главы говорит само за себя — «Базовые компоненты
редакторов». Мы увидим, как они устроены и какими панелями снабжены.
8

В главе 9 будет много кода. Мы рассмотрим общие фрагменты сценариев,
написанные на JavaScript.
Главы 10–13 непосредственно познакомят вас с кодом, который отвечает
за создание и редактирование контента.
Глава 14 рассказывает о записи редактируемых данных в
соответствующие файлы.
И в самой короткой главе 15 подведем итоги нашей работы.
На что еще хотел бы обратить внимание читателя: во избежание
терминологических споров автор ориентировался на определения, данные на
страницах сайта https://developer.mozilla.org/ru/.
1.3. Оформление сценариев
Сценарии имеют различное типографское оформление в соответствии с
их размещением в тексте.
Если код в книге выделен в отдельный блок, то он оформлен
моноширинным шрифтом, например так:
function del()
{
view.style.visibility="hidden";
bas.visibility="hidden";
pict.src="img/net.jpg";
}

Если фрагменты сценария внедрены непосредственно в текст, то в этом
случае части кода выделены полужирным шрифтом, например так:
присваиваем переменной idc новое значение
Обратите внимание: в некоторых блоках программ сделан перенос
части кода на вторую строку (из-за недостатка ширины страницы в книге).
В реальном сценарии код записывается одной строкой. Запомните правило: все переносы строк кода существуют только в их типографском
воспроизведении. Если вы в дальнейшем столкнетесь с подобной
ситуацией, учитывайте данный аспект.
Еще один момент. Многие фрагменты кода в нашем проекте написаны на
PHP. В сети циркулирует придуманная группой программистов концепция так
называемой стандартизации кода — PHP Standards Recommendations (PSR).
Автор считает некоторые рекомендации из данной концепции как минимум
усложняющими чтение программ. Поэтому при создании проекта автор
руководствовался следующими принципами:
– код PHP должен соответствовать официальным стандартам самого языка, а не
рекомендациям каких-либо, пусть даже авторитетных, групп;
– код должен быть оформлен таким образом, чтобы даже самые сложные его
фрагменты легко читались: это в первую очередь касается отступов,
распределения кода по строкам и расположения фигурных скобок.
9

2. Прежде чем начать
До того как мы приступим к написанию редакторов, автор посчитал
необходимым дать некоторую предварительную информацию:
– пояснить смысл терминов, которые нам придется использовать неоднократно;
– рассказать, какие технологии и методы необходимо будет применить в нашем
проекте;
– осветить вопрос, устарели или нет приемы редактирования контента, которые
еще некоторое время назад составляли фундамент почти любого визуального
редактора;
– четко определить, что же мы с вами в конце концов напишем.
Поэтому данный материал я решил выделить пусть и в небольшую, но
самостоятельную главу.
2.1. CMS
Представим такую ситуацию: вы разработали сайт, состоящий из
нескольких HTML-страниц, и разместили его в сети. Пройдет немного времени,
и вы обнаружите, что информацию на одной или нескольких страницах
необходимо отредактировать, а может, и кардинально изменить. Даже самые
стабильные интернет-ресурсы нуждаются в периодическом обновлении, а что
говорить про сайты, которые рассказывают о быстро меняющихся вещах,
например о строительстве жилого микрорайона или о новинках в мире
компьютеров. В таких случаях обновление информации происходит чуть ли не
каждый день.
И вот вы стоите перед задачей ежедневно редактировать одну или
несколько страниц и ставить их вместо устаревших версий. Выглядит это
примерно так: открыли на своем компьютере папку с файлами сайта, добавили
новые рисунки, схемы или фотографии, отредактировали страницу,
подключились к хостингу, закачали новые изображения, заменили страницу,
запустили браузер, проверили полученный результат. Если что-то не
понравилось, вновь правите страницу и закачиваете ее новую версию на
хостинг. Уже чувствуется, что это довольно хлопотное занятие. Между тем,
если бы ваш сайт был снабжен CMS, все оказалось бы гораздо проще:
запустили в браузере систему управления и выполнили все манипуляции через
нее. Не надо подключаться к хостингу, не надо переносить страницу на свой
компьютер, не надо закачивать отредактированную страницу через файловый
менеджер. Еще раз повторюсь: все делается через браузер, без предварительной
обработки данных на своем компьютере.
Обычно CMS — это симбиоз двух продуктов: конструктора сайта и
системы управления сайтом. В сети рекламируется много различных CMS,
например уже упоминавшиеся во введении WordPress, Joomla, Drupal, 1СБитрикс и другие.
Аббревиатура CMS происходит от английского Content management
system, что переводится как «система управления содержимым». Многие
10

современные сайты (если не большинство) управляются такими системами.
CMS позволяют администратору вносить любые изменения на страницы сайта
в онлайн-режиме. Для этого системы управления снабжают WYSIWYGредакторами.
2.2. WYSIWYG
Сайты пишутся на языках программирования HTML и JavaScript, поэтому
редактирование web-страницы — по сути, процесс изменения ее кода. Для
профессионального разработчика это привычное занятие. Но ведь большинство
сайтов программисты создают не для себя, а для клиентов. Много ли среди них
специалистов, досконально знающих HTML и JavaScript? Ответ — единицы.
Значит, для большинства клиентов необходим механизм, который бы позволял
создавать на сайте новые страницы и редактировать существующие без
специальных знаний.
Поэтому креативные программисты придумали не простой редактор, а
WYSIWYG (или, как еще говорят, визуальный редактор). Он отображает
редактируемые материалы практически в том же самом виде, как и на странице
сайта. То есть нажали кнопку BOLD — фрагмент текста действительно
выделился жирным. Нажали кнопку IMG — и появилась настоящая фотография,
а не ее HTML-код.
Термин WYSIWYG — это аббревиатура, произошедшая от английского
выражения «What You See Is What You Get», что в переводе означает «что вы
видите, то вы и получаете». В нашем случае смысл этого выражения таков: что
вы видите в редакторе, то и будет на странице сайта. Очень удобно для
создания и редактирования контента!
Отступление от темы
Вообще, термин WYSIWYG относится не только к разработке визуальных
редакторов для web-проектов. Так называют программы, в которых
содержание выглядит точно так же, как и реальный документ. Например,
всем известный Word — это WYSIWYG-редактор.
2.3. Атрибут contentEditable
Данный атрибут, если он указан в элементе, сообщает браузеру, что этот
элемент — редактируемый.
В чем польза contentEditable? Допустим, есть слой div, в который мы
загружаем предназначенный для редактирования фрагмент web-страницы. Если
у div установлен данный атрибут, мы можем вставлять в слой курсор, выделять,
удалять, добавлять текст, в том числе вводя его с клавиатуры. То есть у нас уже
получился простейший редактор. А если к нему добавить кнопки для импорта в
div HTML-кода рисунков, таблиц, линий и т. д., то у нас выйдет уже
полноценный редактор! Естественно, написанное с нуля или исправленное
11

содержимое слоя можно будет передать специальной программе для записи в
файл или базу данных.
Мы воспользуемся таким подходом при написании второго, третьего и
четвертого редакторов.
Некоторые программисты указывают атрибут contentEditable без
значения. Это не совсем корректно, хотя и будет работать. Как утверждает
https://developer.mozilla.org/ru/, правильно писать
contentEditable="true"

Атрибут можно указать непосредственно в теге, например так:


или присвоить его в JavaScript-сценарии:
document.getElementById("edit").
setAttribute("contenteditable", true);

Обратите внимание! Приведенный выше фрагмент — это пример
переноса строки, сделанный в книге из-за недостатка ширины страницы.
В реальном файле данный код записывается одной строкой! Автор уже
предупреждал о таких переносах во введении. Думаю, читателям все ясно и в
дальнейшем не нужно повторять это правило.
Добавлю, что операция присвоения элементу атрибута в JavaScriptсценарии должна производиться после загрузки страницы:
addEventListener("load", function()
{
document.getElementById("edit").
setAttribute("contenteditable", true);
});

2.4. Свойство designMode
Свойство designMode имеет много общего с contentEditable. Отличие
в том, что designMode устанавливается не для отдельного элемента, а для
всего документа в целом. Когда свойство включено (document.design
Mode="on"), можно редактировать любую HTML-страницу полностью. Эта
особенность натолкнула программистов на идею создания визуальных
редакторов, используя загрузку целой страницы или ее отдельного фрагмента
в iframe.
Процедура включения режима редактирования может выглядеть,
например, так. Пусть на странице редактора есть фрейм, в который загружается
другая HTML-страница, предназначенная для обработки. Тогда в JavaScriptкоде редактора необходимо записать всего одну строку:

12

frames[0].document.designMode="on";

Естественно, данная операция, как и в предыдущем случае, должна
производиться после загрузки страницы:
addEventListener("load", function()
{
frames[0].document.designMode="on";
});

Мы используем свойство designMode в первом редакторе, но будем
обрабатывать не всю страницу сайта, а только ее часть — область контента.
2.5. Метод getSelection
Теперь мы переходим к методам, которые предоставляет в наше
распоряжение JavaScript.
Первым упомянем getSelection. Тут все очень просто: метод возвращает
объект Selection, который содержит выделенный пользователем текст.
Разработчик имеет возможность на программном уровне манипулировать
выделенным фрагментом: форматировать его, копировать, удалять, изменять.
Как выглядит применение метода на практике? Например, у вас есть
редактируемая область контента. Вы выделили в этой области одно или
несколько слов и нажали кнопку BOLD. К тексту, содержащемуся в объекте
Selection, будет добавлена пара тегов b — открывающий и закрывающий.
После этого текущее выделение будет преобразовано к полужирному
начертанию.
Аналогично происходит, если вы просто вставили курсор в какое-либо
место редактируемой области. Объект Selection в этом случае хранит точку
вставки курсора. В эту точку можно поместить рисунок, таблицу, линию,
символ и т. д.
2.6. Отменен ли execCommand?
Метод execCommand служит механизмом внесения изменений в
содержимое web-страницы. Метод получает в качестве аргумента имя команды.
При простом форматировании обычно достаточно одного аргумента, например
execCommand("Bold"). Однако, в некоторых случаях требуется передать три
аргумента: имя команды; значение, указывающее, отображать или нет
пользовательский интерфейс; адрес или текст. Второй аргумент обычно
указывают false. Это означает, что третий аргумент передается в метод
непосредственно из программы. Если указать второй аргумент true, то метод
будет ожидать ввода третьего аргумента пользователем. Более аргументоемкие
варианты execCommand применяются, например, для вставки ссылки или
изображения в редактируемую страницу. В этих случаях сначала указывают
имя, затем false, затем адрес ссылки или картинки.
13

Метод execCommand создан давно. Многие годы на нем строился
фундамент большинства редакторов. Но теперь с ним не все так просто. В связи
с появлением HTML5 некоторые из ранее существовавших команд на
сегодняшний день потеряли свою актуальность (например, fontSize или
fontName).
Более того, на уже упоминавшемся сайте https://developer.mozilla.org/ru/,
на странице, посвященной этому методу, можно прочитать следующее:
«Document.execCommand()
Вышла из употребления
Эта возможность вышла из употребления. Хотя она может продолжать работать
в некоторых браузерах, её использование не рекомендуется, поскольку она
может быть удалена в любое время. Старайтесь избегать её использования».
Однако равнозначной замены этому методу на сегодняшний день нет.
Насколько мне известно, альтернативы пока существуют только в виде не
очень далеко продвинувшихся проектов.
Тем не менее при создании последнего, четвертого, редактора мы
воспользуемся этим методом. Редактор у нас так и будет называться — ретро.
Почему же, невзирая на предупреждения Mozilla, автор тем не менее
предложил редактор на основе такой технологии? Причин четыре.
Первая. Метод продолжает работать в требуемых нам объемах во всех
браузерах, с которыми мне приходилось иметь дело.
Вторая. execCommand до сих пор используется во многих визуальных
редакторах, рекламируемых в сети: например, в CKEditor или в NicEdit.
Третья. Благодаря тому, что многие команды метода унифицированы,
редакторы на основе данного метода получаются самыми «легкими».
Достаточно сравнить сценарии из zip-архива. Файл последнего редактора
editor4.js самый короткий и занимает наименьшее место на диске.
Четвертая, самая важная. Автор не уверен, что на этом методе окончательно
поставлено клеймо устаревшего. Не случиться ли с execCommand то же самое,
что и с HTML? Для тех, кто не в курсе, короткая справка. Был период, когда
Консорциум Всемирной Паутины — World Wide Web Consortium (W3C) —
прекратил дальнейшую разработку языка HTML и попытался заменить его на
XHTML. Из этого ничего не вышло, и тогда HTML возродился в новой,
усовершенствованной и «очищенной» версии — в пятой. И весьма успешно
применяется на протяжении уже нескольких лет. Так вот, не случится ли подобная
история и с execCommand? Для возрождения метода надо совсем немного:
удалить вышедшие из употребления команды и оставить актуальные. Ну, может
быть, добавить еще несколько команд. И у метода начнется вторая жизнь.
Поэтому четвертый редактор был создан из соображений, что еще рано
ставить окончательную точку в деле execCommand. Прекратят браузеры
поддержку этого метода — вы просто не станете пользоваться последним
редактором. Поддержка сохранится — значит редактор останется «на плаву».
У читателя наверняка возникнет вопрос: если альтернативы методу нет,
то как же сделаны первые три редактора? На самом деле есть некоторые
другие — современные — технологии, которые позволяют получить необхо14

димые результаты, но, правда, с большими затратами кода. Они не аналогичны
execCommand, но вполне работоспособны. С ними мы сейчас и познакомимся.
2.7. Методы createElement и surroundContents
Первый метод позволяет создать новый элемент документа, а второй —
добавить его к выделению, полученному методом getSelection. Например, у нас в
редактируемой области есть слово «Важно», которое мы хотим выделить
полужирным шрифтом. Для этого можно написать вот такой сценарий из 4 строк:
let sel=document.getSelection();
let rng=sel.getRangeAt(0);
let elm=document.createElement("b");
rng.surroundContents(elm);

Разберем, что происходит в каждой строке кода.
1. Создаем объект, содержащий выделенный фрагмент текста.
2. Используя метод getRangeAt, создаем объект Range с диапазоном,
равным выделению. Индекс 0 указывает, что выбранный диапазон у нас
единственный.
3. В теле документа методом createElement создаем открывающий и
закрывающий теги элемента b (тег для полужирного начертания шрифта).
4. Методом surroundContents добавляем эти теги перед началом
выделения и после конца выделения.
Теперь редактируемое слово выглядит так: Важно.
Показанный выше пример служит основой первых трех редакторов. Этот
способ позволяет добавлять теги не только к выделенному тексту, но и
вставлять элементы в положение курсора в редактируемой области, например
рисунки, таблицы, линии и т. д.
2.8. Что и как мы напишем
Собственно говоря, все уже написано. Наша задача — разобраться в
принципах создания редакторов и понять технологию их применения.
Итак, у нас есть четыре редактора:
– традиционный;
– с фиксированными стилями;
– креативный;
– ретро.
В этом порядке они и будут разобраны в книге. Откуда взялись такие
названия, выясним в процессе подробного описания каждого из редакторов.
Подчеркну, что особенно выделяется своей необычностью третий редактор,
получивший ярлык «креативный». Но не станем раскрывать секреты раньше
времени. В нужный момент все разъяснится.
Кстати, в креативном редакторе предусмотрена процедура входа для
администратора. В остальных — нет. Сейчас «проникнуть» в остальные
15

редакторы без пароля может любой желающий. Сделано это вот по какой причине.
Особенность «конструкции» третьего редактора такова, что без системы проверки
администратора показывать его просто нет смысла. Почему — поясню в свое
время. Остальные редакторы не обременены проверками, так как автор не хотел
связывать читателей какими-то уже готовыми решениями. Тем, кто возьмется их
воспроизводить, просто хочу напомнить, что вам придется добавить код, который
будет отвечать за «пропускной» режим.
Запись отредактированного контента у всех редакторов выполняет одна и
та же программа на PHP. В ней тоже не предусмотрена проверка, в «законном»
ли порядке поступают данные или от недоброжелателя. Поэтому и в данный
файл нужно будет добавить код проверки.
Подводя черту под темой безопасности, можем констатировать
следующее: проверка входных данных при записи отредактированного
контента и при входе в редактор зависит от способа аутентификации и
авторизации администратора. Каковы будут эти способы — решать вам.
Пойдем дальше. Если есть редакторы, значит, они должны что-то
редактировать. В качестве ресурса для экспериментов у нас есть
демонстрационный сайт, посвященный космической тематике. В нем пять
страниц. Одна уже наполнена контентом, остальные — пустые. Таким образом,
тот, кто возьмется экспериментировать с редакторами, может как изменять
существующие данные, так и создавать новые на пустых страницах. При этом
еще раз обращаю внимание: в демонстрационных редакторах функции записи
изменений в контенте отключены.
При создании проекта не использовалась база данных. Вся информация,
размещенная на сайте, хранится в простых текстовых файлах. Сделано это по
двум причинам:
– сайту нечего скрывать, так как никакой секретной информации он не
содержит;
– так проект получается проще и доступнее для повторения.
Естественно, при желании вы можете переписать соответствующие
фрагменты кода для взаимодействия с базами данных.
Создавая файлы управления редакторами, автор старался соблюсти
баланс между оптимизацией и читабельностью кода. При этом все такие файлы
написаны на чистом, или, как еще говорят, ванильном, JavaScript, то есть без
использования библиотек и фреймворков типа jQuery.
Отступление от темы
Vanilla JS — http://vanilla-js.com/ — шуточный сайт кроссплатформенного
фреймворка Vanilla JS, под которым подразумевается чистый JavaScript. Его
автор ставит целью напомнить разработчикам, что довольно часто при
создании кода можно обойтись без библиотек и фреймворков. В очень многих
случаях писать программы на чистом JavaScript гораздо продуктивнее и
рациональнее. От имени сайта и образовалось это выражение — «ванильный
JavaScript», то есть JavaScript в его первозданном виде.
16

Описанные в книге программы могут быть использованы как составная
часть какой-либо самодельной CMS (понимаю, что не один я занимаюсь
подобным творчеством) или как ориентир при написании разработчиками
собственных редакторов.
Обращу ваше внимание на еще один важный момент. Если редакторы
применяются самостоятельно, необходимо предусмотреть дополнительную
программу, которая позволяла бы закачивать и удалять изображения, создавать
новые и удалять старые страницы, редактировать меню и блок рекламы.
Конечно, это можно делать вручную, но очень неудобно. Гораздо
производительнее доверить эти процессы специальному web-приложению к
редактору. Для выполнения перечисленных задач вполне подойдет
одностраничное приложение.

17

3. Среда разработки
Для написания и тестирования сайта и редакторов нам в обязательном
порядке необходимо создать на своем компьютере локальный хостинг.
Вообще, хостинг — это, упрощенно говоря, компьютер, предназначенный
для размещения на нем сайтов и обеспечивающий к ним доступ из Интернета.
Локальный хостинг — набор программ на вашем персональном компьютере,
которые позволяют имитировать реальный хостинг и проводить тестирование
ваших сайтов (включая HTML-страницы и серверные скрипты) перед их
размещением в сети. Кстати, обратите внимание: локальный хостинг работает
без подключения к Интернету!
Первая ошибка, которую допускают многие начинающие программисты,
состоит в попытках создать локальный хостинг, следуя описаниям из
Интернета, где предлагаются «навороченные» методы. Их авторы выделяют на
диске C отдельные сектора, создают кучу дополнительных директорий, вносят
большое количество изменений в конфигурационные файлы. В результате
неопытный человек начинает путаться в этих сложных описаниях, ошибаться в
настройках программного обеспечения и лишь путем многочисленных проб и
консультаций с энной попытки наконец получает требуемый результат (а
иногда так и не получает, из-за чего начинает искать другие описания на
данную тему). Между тем создание хостинга на своем ПК — дело несложное.
Чтобы получить результаты, описанные в данной книге, вам
понадобиться установить на компьютер распространяемый пакет компонентов
Visual C++ от Microsoft, сервер Apache и интерпретатор PHP. Описание
технологии их установки — в следующих разделах.
Полноценную среду разработки невозможно представить без установки
на ваш компьютер настоящего текстового редактора, специально
предназначенного для создания программ. Конечно, весь код можно писать в
обычном «Блокноте». Но гораздо лучше и рациональнее пользоваться
специализированными редакторами. Такие приложения намного удобнее: они
подсвечивают код, предлагают синтаксические подсказки, позволяют менять
кодировку документов, сохраняют файлы в разных форматах.
В нашем случае необходим редактор, который позволит:
– выполнять качественную разметку;
– создавать файлы с таблицами стилей;
– писать сценарии на JavaScript;
– делать на языке программирования PHP компоновщики HTML-страниц.
Этим принципам удовлетворяют многие редакторы. Но лучше всего, на
мой взгляд, Notepad++. Где его взять и как установить, рассказано в пятом
разделе этой главы.
Итак, вводная часть завершена — приступим к созданию локального
хостинга. А начнем мы с выяснения разрядности вашей ОС.
Обратите внимание: все процедуры описаны для компьютера с
операционной системой Windows 10.
18

3.1. Выясняем разрядность ОС
Перед тем как мы создадим на компьютере среду разработки, необходимо выяснить разрядность вашей операционной системы, чтобы знать,
какие файлы скачивать для локального хостинга.

Рис. 3.1.1. Кнопка «Параметры» в меню

Рис. 3.1.2. Разрядность или тип операционной системы

Включите компьютер, дождитесь полной загрузки операционной системы.
Щелкните на кнопке «Пуск», а затем на кнопке «Параметры» (рис. 3.1.1).
19

В открывшемся окне выберите пункт меню «Система». Откроется следующая
вкладка, в которой необходимо кликнуть на строке «О системе». После этого на
вкладке «Характеристики устройства» посмотрите строку «Тип системы»
(рис. 3.1.2).
Типов ОС Windows существует два — 32-разрядная и 64-разрядная.
Запомните разрядность вашей. Это число понадобится трижды: при скачивании
пакета Visual C++, а также zip-архивов сервера Apache и интерпретатора PHP.
3.2. Установка пакета Visual C++
Откройте браузер и зайдите на страницу https://www.apachelounge.com/
download/. Это сайт, с которого мы будем скачивать архив с сервером Apache.
Но сначала надо установить на ваш компьютер компоненты Visual C++, без
которых сервер не заработает.
Для этого найдите на указанной странице текст «Be sure you installed
latest 14.29.30037.0 Visual C++ Redistributable for Visual Studio 2015-2019:
vc_redist_x64 or vc_redist_x86 see Redistributable» (на момент подготовки
книги данные строки были последними в описательной части страницы; со
временем текст может несколько измениться). Для нас важны две ссылки,
расположенные в тексте: vc_redist_x64 и vc_redist_x86. Если у вас 64разрядная ОС, нажмите ссылку vc_redist_x64. Если 32-разрядная, необходимо
щелкнуть на ссылке vc_redist_x86 (рис. 3.2.1).

Рис. 3.2.1. Ссылки для скачивания пакетов Visual C++
20

Запустите скачанный файл (рис. 3.2.2). Примите условия лицензионного
соглашения и нажмите кнопку «Установить». Дождитесь завершения процесса
установки (рис. 3.2.3). Нажмите кнопку «Закрыть» (рис. 3.2.4).

Рис. 3.2.2. Начало установки компилятора

Рис. 3.2.3. Процесс установки

Рис. 3.2.4. Завершение установки
21

3.3. Установка сервера Apache 2.4
Теперь
скачайте
на
рабочий
стол
компьютера
с
сайта
https://www.apachelounge.com/download/ zip-архив сервера, соответствующий
разрядности вашей ОС (рис. 3.3.1). Для 64-разрядной системы — архив с
пометкой Win64 (файл httpd-2.4.48-win64-VS16.zip), для 32-разрядной — с
пометкой Win32 (файл httpd-2.4.48-win32-VS16.zip). Распакуйте архив.
Скопируйте папку Apache24 (только ее) непосредственно на диск C, чтобы ее
адрес был C:\Apache24 (рис. 3.3.2).

Рис. 3.3.1. Сайт с zip-архивом сервера

Рис. 3.3.2. Копируем папку Apache24 на диск C

Откройте приложение «Командная строка» от имени администратора.
Для этого нажмите кнопку «Пуск», в меню выберите «Служебные —
Windows», найдите пункт «Командная строка» и щелкните на немправой
(правой!) кнопкой мыши. В выпадающем списке выберите «Дополнительно»,
а затем «Запуск от имени администратора» (рис. 3.3.3). Откроется окно
программы.

22

Рис. 3.3.3. Запуск командной строки

Теперь надо инсталлировать, а затем запустить сервер. Для этого в окне
командной строки сразу после
C:\WINDOWS\System32>

наберите
C:\Apache24\bin\httpd.exe -k install

Должно получиться
C:\WINDOWS\System32>C:\Apache24\bin\httpd.exe -k install

Нажмите «Enter». Когда процесс инсталляции закончится (рис. 3.3.4), в окне
программы вновь появится строка
C:\WINDOWS\System32>

Закройте окно командной строки и перезагрузите компьютер.
23

ВНИМАНИЕ! Может открыться окно брандмауэра с запросом на
разрешение работы «Apache». Разрешите доступ во всех сетях.
Нам надо убедиться, что сервер заработал. Для этого откройте ваш браузер и
введите в строке адреса http://localhost/. Если появилось сообщение «It works!»,
значит, все в порядке — сервер функционирует как положено (рис. 3.3.5).

Рис. 3.3.4. Инсталляция сервера из приложения «Командная строка»

Рис. 3.3.5. Сервер подтверждает, что он работает

Теперь обратите внимание на один важный момент. Метод, которым мы
установили сервер, позволяет запускать его автоматически при включении
компьютера и завершать его работу при выключении компьютера. То есть
Apache продолжает функционировать, даже если в данное время он вам не
нужен. Эта информация вызывает у вас беспокойство по поводу теоретической
уязвимости ПК? Тогда переведите сервер в режим ручного запуска. Для этого
выполните следующие действия:
– введите в строке поиска слово «службы» (рис. 3.3.6) и нажмите на
соответствующую иконку, которая появится в списке результатов поиска;
– в открывшемся окне найдите строку «Apache2.4» и щелкните по ней
правой (правой!) кнопкой мыши — появится меню управления службой
(рис. 3.3.7);
– кликните на строке «Свойства» и в окне на вкладке «Общие» найдите
список «Тип запуска»;
– выберите пункт «Вручную», затем последовательно нажмите кнопки
«Применить» и «ОК» (рис. 3.3.8);
– теперь остановите службу, нажав соответствующую ссылку в левой
стороне окна (рис. 3.3.9);
24

– дождитесь окончания процесса (рис. 3.3.10);
– закройте вкладку «Службы».

Рис. 3.3.6. Находим приложение «Службы»

Рис. 3.3.7. Открываем меню управления службой

25

Рис. 3.3.8. Переводим службу в режим ручного запуска

Рис. 3.3.9. Нажимаем ссылку «Остановить службу»

26

Рис. 3.3.10. Идет процесс остановки Apache

Рис. 3.3.11. Для запуска Apache нажмите ссылку «Запустить службу»

27

Рис. 3.3.12. Идет процесс запуска сервера

Теперь Apache остановлен и переведен в режим ручного запуска. При
необходимости воспользоваться сервером снова зайдите в раздел «Службы»,
выделите строку «Apache2.4» и кликните на ссылке «Запустить службу»
(рис. 3.3.11). Дождитесь окончания процесса (3.3.12).
Продолжаете беспокоиться о безопасности? Можете на время работы с
сервером отключать свой ПК от Интернета. Напомню — локальный хостинг
работает без сети.
3.4. Установка PHP 8
Скачайте на рабочий стол компьютера с сайта https://windows.php.net/
download/ zip-архив PHP 8, соответствующий разрядности вашей ОС. Для 64разрядной системы — архив с пометкой x64, для 32-разрядной — с пометкой
x86. Обратите внимание: так как мы будем устанавливать PHP в качестве
модуля сервера Apache, скачивать надо дистрибутив Thread Safe (рис. 3.4.1).
Распакуйте архив. Переименуйте распакованную папку на php и
переместите ее непосредственно на диск C, чтобы ее адрес был C:\php (рис. 3.4.2).
В папке C:\Apache24\conf с помощью текстового редактора «Блокнот»
откройте файл httpd.conf (рис. 3.4.3), найдите в нем строку
DirectoryIndex index.html
28

и добавьте к ней
index.php

Должно получиться
DirectoryIndex index.html index.php

Теперь в самый конец файла httpd.conf добавьте 2 строки:
AddHandler application/x-httpd-php .php
LoadModule php_module "C:/php/php8apache2_4.dll"

Сохраните изменения, закройте файл и перезагрузите компьютер.
Убедимся, что PHP заработал. Для этого в папке C:\Apache24\htdocs
создайте текстовый файл и запишите в него следующий код :



Составляем путь к файлу на основе полученного адреса страницы $adr:
$stran="content/".$adr.".txt";

за один раз считываем все содержимое файла
$soder=file_get_contents($stran);

и выводим его на страницу:
echo $soder;

В заключение несколько рассуждений о безопасности. Использованный
нами метод загрузки страницы хорош по двум причинам.
1. Мы не указываем в адресе расширение к имени файла, а добавляем его
программным методом. Это расширение строго ограничено одним вариантом — .txt.
2. Мы сравниваем имя файла с реально существующими именами из
соответствующей папки и формируем строго ограниченный путь.
Таким образом, даже если недоброжелатель захочет ввести какой-либо
иной адрес, какой-либо иной путь, чтобы с помощью нашей программы
index.php открыть или запустить на сервере файл, не предназначенный для
посторонних, у него ничего не выйдет. При любых действиях просто откроется
главная страница сайта.
57

7. Структура редакторов
Как выглядит типичный визуальный редактор? Примерно таким образом:
окно редактирования и набор кнопок, выполняющих определенные действия с
текстом, изображением, таблицами и т. п. Чаще всего в стандартном редакторе еще
предусмотрен режим переключения на вкладку с HTML-кодом, чтобы опытный
пользователь мог при желании подправить какие-либо фрагменты. При этом в окне
визуального редактирования сразу видно, что получится после записи содержимого
в файл или базу данных. И лишь одно вы не сможете посмотреть заранее, еще до
записи: коррелируются ли результаты вашего творчества с дизайном страницы и
сочетается ли созданный вами контент с остальными элементами.
Наш проект избавлен от этого недостатка. Все представленные в книге
редакторы позволяют администратору сайта видеть, как будет выглядеть страница
еще до записи внесенных изменений. Такой результат достигается за счет того,
что в редакторах № 1, 2 и 4 есть встроенные фреймы, в которые загружаются
редактируемые страницы. При этом каждое изменение в окне редактора тут же
отображается и в области контента страницы. За счет этого вы можете сразу
оценить совпадение стилей редактируемых элементов с дизайном сайта.
Редактор № 3 также позволяет «в прямом эфире» наблюдать за
соответствием вносимых изменений дизайну ресурса, но иным способом, о чем
автор расскажет в свое время.
Основная, базовая структура редакторов № 1, 2 и 4 идентична. В них есть:
– вкладка с окном визуального редактирования;
– вкладка с окном HTML-редактора;
– главная панель с набором основных кнопок;
– скрытые панели настроек элементов, которые появляются при нажатии
соответствующих кнопок главной панели;
– фрейм со страницей, основное содержание которой загружено в
редактор.
Структура редактора № 3 несколько отличается от изложенной выше. Ее
мы разберем в главе 12.
7.1. Пишем заготовку
Компоновка страниц редакторов № 1, 2 и 4 показана на рисунке 7.1.1.
Чтобы получить данную структуру, напишем следующий HTML-шаблон:





Визуальный редактор
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
|
| Подключаем таблицы стилей и файл сценария |
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|
58




_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
|
| Вкладки настроек
|
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|

_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
|
| Главная панель
|
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|

_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
| Кнопки переключения между редакторами
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
| Текстовый и WYSIWYG-редакторы
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
| Фрейм со страницей сайта
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

_ _
|
|
_ _|
_ _
|
|
_ _|
_ _
|
|
_ _|





Первое новшество, по сравнению с кодом разметки сайта, — мета-тег
robots в заголовочной части:


Данный фрагмент запрещает поисковым роботам индексирование документа и
переход с него по ссылкам, если они есть в текстах данной страницы.
Остальная часть разметки довольно простая. Есть основа каждой
страницы — слой div:

...


Его настройки в таблице стилей таковы, что ширина страницы 1000px,
высота — 1410px, а располагается она строго посередине окна браузера:
#basis {position: relative; width: 1000px;
height: 1410px; margin: auto;}

59

Думаю, назначение остальных компонентов структуры понятно без
лишних комментариев. Подробнее об окнах редактирования, элементах главной
панели, вкладок будет рассказано в главе 8.

Рис. 7.1.1. Компоновка страницы редактора (за исключением третьего — креативного)

7.2. Файл таблицы стилей
Файлы с таблицами стилей, как и у сайта, подключаем обычным
способом, поместив необходимые инструкции в головной части документа. Так
как в структурах редакторов есть некоторые отличия, каждый из них имеет
свой собственный файл CSS. Создавая проект, автор решил не писать единой
таблицы стилей, так как в этом случае, выбрав какой-то один редактор, вы
получили бы к нему CSS-файл с избыточным кодом. Это несколько
«утяжеляет» zip-архив, но «облегчает» каждый редактор в отдельности.
На примере второго редактора покажем внедрение таблиц стилей в код
страницы:


60

Важно! Вторая таблица стилей с адресом set/cont.css импортируется
только во второй редактор. Другим редакторам она не нужна.
7.3. Файл со сценариями
Каждый редактор имеет персональный файл сценариев на JavaScript.
Покажем его подключение на примере редактора № 1:


Как и в ситуации с таблицами стилей, автор решил не писать единого
файла сценария, так как в этом случае получилась бы огромная программа с
таким количеством кода, что разбираться в нем было бы проблематично.
Отдельные файлы, хотя и содержат повторяющиеся фрагменты, заметно короче
и проще читаются. При этом повторяется ситуация, когда несколько программ
«утяжеляют» zip-архив, но «облегчают» каждый редактор в отдельности.
Основные функции таких файлов:
– выбор загружаемой страницы;
– загрузка основного содержания в окно визуального редактора;
– обеспечение взаимодействия WYSIWYG и текстового редакторов;
– открытие и закрытие вкладок с настройками;
– простое редактирование текста — преобразование его фрагментов к
полужирному, подчеркнутому, наклонному начертанию и т. п.;
– удаление форматирования из текста;
– добавление различных элементов — рисунков, таблиц, линий и т. д.;
– непрерывная передача результатов из окна редактора в область
контента редактируемой страницы для наблюдения за соответствием
внесенных изменений дизайну сайта;
– навигация по внесенным изменениям с возможностью отмены и
возврата промежуточных результатов;
– отправка данных для записи;
– вывод сообщений, подтверждающих успешную запись.
7.4. Добавляем фрейм для просмотра страницы
Как уже было сказано выше, для наблюдения за соответствием вносимых
изменений дизайну сайта в нижней части страницы редакторов № 1, 2 и 4 есть
фрейм, куда загружается редактируемая страница:


Назначение страницы vacant.html мы уже объясняли: она носит чисто
декоративную функцию на случай проверки разметки редактора в валидаторе
HTML.

61

7.5. Дизайн редакторов
Полную страницу редактора вы можете видеть на рисунке 7.5.1.

Рис. 7.5.1. Редактор № 1 с загруженной главной страницей

62

В исходном состоянии вкладки настроек не видны. Они выводятся поверх
главной панели при нажатии соответствующих кнопок редактирования. Чтобы
скрыть вкладку, необходимо щелкнуть на пиктограмме закрытия или на кнопке
«Вставить».
Главная панель, помимо кнопок редактирования, содержит:
– список страниц, которые могут быть загружены в редактор;
– кнопку записи результатов редактирования;
– кнопки навигации по внесенным изменениям.
Для переключения с визуального редактора на HTML и обратно
используются вкладки WYSIWYG и HTML. Вкладка неактивного в данный
момент окна редактирования выделяется синим цветом.
7.6. Подключаем PHP
Оболочка PHP любого из редакторов используется чаще, чем аналогичная
оболочка сайта. Совпадает одна функция — проверки адреса запрошенной
страницы. Этот адрес нужен, чтобы:
– при отправке отредактированных данных сообщить программе rec.php,
в какой файл необходимо произвести запись;
– загрузить во фрейм необходимую страницу и получить из нее
редактируемое содержимое.
Также PHP требуется для загрузки списка существующих на сервере
фотографий, списка внутренних страниц сайта (для внутренних ссылок) и
списка страниц, которые можно загрузить в редактор. О последних трех
случаях использования PHP мы поговорим в главе 8.
Кроме того, считаю необходимым напомнить, что во всех редакторах, за
исключением «креативного», не предусмотрена проверка, откуда поступает запрос:
от авторизованного источника или от недоброжелателя. Поэтому в файлы
редакторов № 1, 2 и 4 нужно будет добавить код проверки, который зависит от
способа аутентификации и авторизации администратора. Выбор способа — за вами.
Итак, проверка введенного адреса. Сначала выясняем, указан ли в запросе
параметр с адресом страницы:
if(isset($_GET["a"]))

Если да, то присваиваем значение параметра переменной $test_adr:
$test_adr=$_GET["a"];

Если нет, это, скорее всего, означает, что-либо ошибся администратор, либо в
редактор пытается проникнуть недоброжелатель. Выводим предупреждение об
ошибке и на всякий случай прерываем выполнение программы (а не загружаем
главную страницу, как в файле сайта):
else
{
63

echo "НЕКОРРЕКТНЫЙ ЗАПРОС!";
return;
}

Данные поступили? В этом случае создаем переменную-идентификатор
$ch:
$ch=0;

и проверяем, существует ли текстовая страница с адресом из запроса. Для этого
поочередно выясняем имена всех файлов из папки content
$opdir=opendir("content");
while($redir=readdir($opdir))
{
...
}
closedir($opdir);

и сравниваем их с адресом, переданным в запросе:
if($test_adr.".txt"==$redir)
{
...
}

Совпадения не обнаружены? Опять проблема может быть в ошибке
администратора или в попытке недоброжелателя загрузить страницу, не
предназначенную для доступа постороннему. В этой ситуации переменнаяидентификатор не изменит своего значения, что служит сигналом для вывода
предупреждения и остановки программы:
if($ch==0)
{
echo "НЕКОРРЕКТНЫЙ АДРЕС !";
return;
}

Совпадение обнаружено? Следуют три действия:
– создаем новую переменную $adr, которая получает значение — адрес
страницы, предназначенной для загрузки в редактор:
$adr=$test_adr;

– присваиваем идентификатору новое значение:
$ch=1;

– прерываем цикл:
break;
64

Полный код блока проверки:
if(isset($_GET["a"]))
$test_adr=$_GET["a"];
else
{
echo "НЕКОРРЕКТНЫЙ ЗАПРОС !";
return;
}
$ch=0;
$opdir=opendir("content");
while($redir=readdir($opdir))
{
if($test_adr.".txt"==$redir)
{
$adr=$test_adr;
$ch=1;
break;
}
}
closedir($opdir);
if($ch==0)
{
echo "НЕКОРРЕКТНЫЙ АДРЕС !";
return;
}

Отступление от темы
Любопытно, что PHP 8 стал более строг по отношению к параметрам.
Раньше можно было просто написать $test_adr=$_GET["a"] и не заботиться
о том, существует ли данный параметр в запросе или нет. В любом случае
проверка условия if($test_adr.".txt"==$redir) прошла бы корректно. В PHP 8
такой подход при отсутствии в запросе параметра вызовет ошибку. Поэтому
автор рекомендует всегда проверять наличие параметра, например так:
if(isset($_GET["a"])).
Следующий этап — присвоение имени страницы скрытому полю, из
которого при передаче данных программа на сервере извлечет информацию о
том, в какой файл необходимо производить запись:

...



Основное действующее лицо здесь — PHP.
Во-первых, сценарий формирует установленную по умолчанию строку в
выпадающем списке на основе переменной $adr, значение которой получено в
процессе загрузки страницы:




Как видите, здесь вновь задействован PHP. Сначала мы открываем папку
cosmos
$opdir=opendir("cosmos");

и считываем из нее все содержимое:
while($redir=readdir($opdir))
{
...
}
closedir($opdir);

Напомню, что в список попадут такие элементы, как точка и две точки
(. и ..), которые символизируют текущий и вышестоящий каталоги. Чтобы
удалить их, выполняем следующую проверку:
if(strpos($redir, "."))

Точка и две точки возвратят индекс первого вхождения элемента — ноль.
Условие if воспримет данный результат как false и не включит эти элементы в
список изображений. Зато у остальных картинок, у которых точка стоит перед
расширением после нескольких символов имени файла, индекс вхождения
окажется больше нуля, и условие примет значение true. То есть реальные
фотографии окажутся на вкладке:
echo '';

8.7. Блок настроек фреймов
Окно с элементами настройки фреймов показано на рисунке 8.7.1.
Обязательным параметром является адрес страницы. При его отсутствии
появится предупреждение: «Вы не указали адрес загружаемой страницы!».
84

Кроме того, вы можете:
– настроить размеры фрейма;
– выбрать его позиционирование (графа «Положение»);
– установить толщину рамки и ее цвет;
– задать внешний зазор от окружающих элементов или текста.
При отсутствии необходимых параметров вставляется фрейм с черной
рамкой толщиной 1px и размерами в соответствии с внутренними установками
браузера (обычно ширина такого фрейма примерно 300 пикселей).

Рис. 8.7.1. Окно настройки фреймов

Обратите внимание: в окне фрейма будет показана страница,
загруженная только по протоколу https. Так происходит во всех браузерах —
из соображений безопасности.
Код вкладки с настройками фреймов:



Адрес загружаемой страницы:

Ширина, px:

Высота, px:
Положение:
НЕТ
Слева
Справа

Рамка, px:
Цвет рамки:

Внешний зазор, px:

85




Отступление от темы
Среди некоторых программистов бытует мнение, что фреймы устарели. Это
не соответствует действительности. Даже такие передовые лидеры webиндустрии, как Google или YouTube, используют фреймы. Например, первый —
для встраивания пользователем карт местности, а второй — в функции
«Поделиться видео».
8.8. Блок выбора символов
Панель с различными математическими и не только символами показана
на рисунке 8.8.1. Работать с ней очень просто: вставляете курсор в необходимое
место окна редактирования и нажимаете кнопку требуемого символа, после
чего панель закрывается, а символ появляется в тексте.
Вообще, полезных символов очень много — но автор выбрал лишь 50
наиболее часто применяемых (на его взгляд).

Рис. 8.8.1. Окно выбора символов

Код вкладки занимает в документе довольно большой объем, поэтому
приведем его в сокращенном виде:




...



...
86





В коде страницы почти все символы записаны в виде HTML-сущностей:
¥, § и так далее. В окне редактирования они преобразуются в
реальные символы.
8.9. Блок настроек ссылок
Блок настроек ссылок показан на рисунке 8.9.1.
Окно редактирования позволяет создать ссылку на внешний ресурс, на
внутреннюю страницу сайта или на электронную почту.
Помимо адреса вы можете указать:
– для внешней ссылки — открывать ли ее в новом окне или нет (не
действует для внутренней ссылки);
– тип протокола соединения — https, http или mailto;
– нужно ли подчеркивать ссылку или нет;
– цвет текста ссылки.
Выбор между внешней и внутренней ссылкой происходит по следующей
схеме:
– если введен адрес стороннего ресурса, то добавляется именно он;
– в остальных случаях добавляется ссылка на внутреннюю страницу.
Начальные установки вкладки после ее открытия: выбрана внутренняя
страница, цвет ссылки — черный, с подчеркиванием.
Чтобы добавить ссылку, откройте вкладку, выполните требуемые
настройки, выделите текст и нажмите кнопку «Вставить». Забыли сделать
выделение? Появится окно с предупреждением.
Код вкладки:



Добавить ссылку на внешний ресурс:

https://
http://
mailto:



Открывать ссылку в новом окне:

ДА
НЕТ
87


Добавить ссылку на страницу:

...


Оформление:

С подчеркиванием
Без подчеркивания

Цвет:




Рис. 8.9.1. Окно настроек ссылок

Отдельно разберем, как создается выпадающий список «Добавить ссылку
на страницу»:

...


Здесь мы в который раз прибегаем к помощи PHP:


Очень похоже на то, что мы делали, когда формировали список файлов
для главной панели. Здесь практически все то же самое, но за тремя
исключениями.
1. У панели на вершине списка было имя загруженной страницы. Теперь
нам не требуется создавать преимущество какому-либо файлу. На вершине
оказывается имя первого обнаруженного в цикле просмотра папки content.
2. Из первого пункта автоматически вытекает второй: сейчас проверка на
имя файла не нужна. Нам достаточно убедиться, что очередной элемент из
цикла не является символом текущего или вышестоящего каталога:
if(strpos($redir, "."))

3. Введена дополнительная переменная $ident, которая служит
идентификатором заполнения первой строки перечня. Соответственно, в цикле
делается проверка:
if($ident==0)
{
...
}
else

Первая строка формируется следующим образом:
if($ident==0)
{
echo ''
.$rep.'';
...
}

После этого идентификатору присваивается новое значение:
$ident=1;

Теперь выражение
if($ident==0)

89

дает результат false и выполняется второй блок условия, в котором записана
инструкция печати остальных имен файлов:
echo ''.$rep.'';

8.10. Блок настроек заголовков
Вкладка настроек заголовков изображена на рисунке 8.10.1. В данном
окне вы можете выбрать:
– уровень заголовка от h1 до h6;
– шрифт, размер шрифта и его цвет.
Как видно из рисунка, по умолчанию для заголовка установлен первый
уровень и шрифт «Tahoma» черного цвета. Пустует только поле для ввода кегля
(размера). Если все так и оставить, размер для h1 будет примерно 32px.
Откройте вкладку, выполните требуемые настройки, выделите текст,
который станет заголовком, и нажмите кнопку «Вставить».

Рис. 8.10.1. Вкладка настроек заголовков

HTML-код блока настроек заголовков:



Заголовок:
h1
h2
...
h6

Шрифт:
Tahoma
Arial
...

Times New Roman

Размер, px:
90

Цвет шрифта:





8.11. Блок настроек выравнивания текста в абзацах
Панель настроек выравнивания текста в абзацах изображена на
рисунке 8.11.1. Как видите, здесь 5 полей. Создавая такую вкладку, автор
руководствовался следующим соображением: выделяя часть текста в
отдельный абзац, администратор, наверное, предполагает, что текст будет
иметь какое-то оформление. Так почему этот процесс надо разбивать на две или
три операции, когда все можно совместить в одной? Делать все настройки за
один присест, на взгляд автора, рациональнее, быстрее и проще.
Поэтому в данном окне вы можете выбрать:
– выравнивание по левому или правому краю, по центру, по ширине
страницы;
– шрифт, его размер и цвет;
– отступ первой строки абзаца от левого края.
На третий пункт обратите особое внимание. В этом параметре можно
указывать не только положительные числа, но также и отрицательные,
например так: –50px. В последнем случае образуется не отступ, а выступ
начала первой строки левее левого края остального текста.

Рис. 8.11.1. Панель настроек выравнивания текста в абзацах

Код блока настроек выравнивания текста:



91

Выравнивание:
По левому краю

По центру
По правому краю
По ширине

Шрифт:
Tahoma
Arial
...

Times New Roman

Размер, px:

Цвет шрифта:

Отступ начала абзаца, px:





8.12. Блок настроек шрифтов
Окно настроек шрифтов показано на рисунке 8.12.1. У читателя может
появиться вопрос: зачем такое окно, если все предварительные установки
можно выполнить, создавая абзац? Ответ очень простой: отдельная настройка
необходима на случай, если надо выделить одно или несколько слов шрифтом,
отличающимся от остального текста.
Панель имеет уже хорошо знакомые вам три параметра: шрифт, цвет и
размер в пикселях.
Так как в этом окне нет каких-либо особенностей, на которые необходимо
обратить внимание, просто посмотрим его HTML-код. Он максимально прост:



Шрифт:
Tahoma
Arial
...

Times New Roman

Размер, px:
Цвет шрифта:
92





Рис. 8.12.1. Блок настроек шрифтов

8.13. Блок настроек цвета текста
Последняя из рассматриваемых функций — настройка цвета текста — не
имеет персонального окна. Все делается непосредственно с главной панели. На
рисунке 8.13.1 стрелками показаны кнопки, выполняющие заявленные
операции. Их три: изменение цвета текста, выбор цвета, изменение цвета фона
под текстом.

Рис. 8.13.1. Кнопки настроек цвета текста

Работает все очень просто. Нажмите кнопку открытия окна выбора цвета
(на рисунке 8.13.1 эта кнопка обозначена средней стрелкой). Выберите
требуемый тон, передвигая круглый ползунок по цветовой шкале (обозначен
нижней стрелкой на рисунке 8.13.2). Перемещая круглый курсор (обозначен
верхней стрелкой на рисунке 8.13.2) по прямоугольнику палитры, выберите
необходимый оттенок. Выделите текст. Для изменения цвета букв нажмите
кнопку с символом «А» синего цвета (левая на рисунке 8.13.1). Для изменения
цвета фона под текстом нажмите кнопку с буквой «А» на синем фоне (правая
на рисунке 8.13.1).

93

Рис. 8.13.2. Выбор цвета текста или его фона

Код, создающий элементы управления цветом:




8.14. Удаление форматирования и ссылки
В заключение — короткая справка о том, как работают кнопки удаления
форматирования и удаления ссылки в разных версиях редакторов.
Во-первых, в редакторах № 1–3 действие этих кнопок абсолютно
одинаково — они исключают из текста все HTML-теги, которые там есть,
оставляя только сам текст. Таким образом, если в выделение попадет, например,
ссылка, она тоже будет удалена вместе с такими тегами форматирования, как p,
span, b, i и т. д. На резонный вопрос, зачем тогда две разные кнопки — удаления форматирования и удаления ссылки, если они выполняют одну и ту же
функцию, есть резонный ответ: в последнем, четвертом редакторе эти кнопки
действуют по-разному. Поэтому для соблюдения идентичности главной панели
во всех версиях редакторов в первых трех были сохранены обе кнопки.
Во-вторых, чтобы удалить форматирование из фрагмента текста, в
редакторах № 1–3 необходимо сделать выделение на один символ больше слева
и справа. Как это выглядит на практике? Допустим, у вас есть слово
«визуальный» с буквами аль полужирного начертания. Чтобы привести их к
нормальному отображению, надо выделить мышью буквы уальн и нажать
кнопку удаления форматирования (выделение должно выглядеть так:
визуальный). Если у вас есть фрагмент текста «этот визуальный редактор», в
котором полужирным шрифтом набрано слово «визуальный», то для его
94

приведения к исходному состоянию надо выделить не только само слово, но и
пробелы до соседних слов (вот так: этот визуальный редактор).
В-третьих, про последний, четвертый, редактор. В нем кнопка удаления
форматирования удаляет из текста действительно только теги форматирования
и стили из попавших в выделение ссылок, не трогая последние. Кнопка
удаления ссылки удаляет только ее, оставляя служащий основой ссылки текст.
При этом в обоих случаях дополнительные символы по краям выделять не надо.
На этом разговор о кнопках и вкладках завершен. Теперь перейдем к
самому главному — сценариям на JavaScript, которые управляют всеми
процессами редактирования и записи данных.

95

9. Общие фрагменты сценариев
Любой редактор состоит из трех «ингредиентов»: файла страницы,
таблицы стилей и файла со сценариями, написанными на JavaScript. По сути,
JavaScript — это квинтэссенция, альфа и омега, основа нашего проекта. Именно
сценарии меняют или создают контент для сайта. При этом каждый редактор
обеспечен своим персональным набором сценариев, объединенных в одну
программу.
Уже неоднократно было упомянуто, что редакторы имеют как
определенные различия, так и набор одинаковых или почти одинаковых
компонентов. Про отличия мы будем говорить, когда станем подробно
разбирать каждую версию в отдельности. Сейчас речь пойдет о блоках кода
JavaScript, которые есть в любом из редакторов и которые в одних случаях
полностью, а в других почти полностью (за некоторыми незначительными
различиями) схожи.
Перечислим совпадающие компоненты наших JavaScript-файлов:
– «главный» обработчик, служащий контейнером для всех остальных
обработчиков и функций;
– инструкции выбора загружаемой страницы;
– инструкции, обеспечивающие взаимодействие визуального и текстового
редакторов;
– всего одна строка кода для фиксации выделенной области в окне
визуального редактора;
– функции открытия и закрытия вкладок с настройками;
– сценарий выбора рисунка с сервера (то есть из папки cosmos);
– блок навигации по истории внесенных изменений с возможностью
зафиксировать начальный, конечный или любой промежуточный результат;
– блок записи контента отредактированной страницы.
Двинемся по порядку.
9.1. Регистрация «главного» обработчика
Один из самых простых фрагментов кода, абсолютно одинаковый для
всех редакторов. Как вы помните, файл JavaScript мы подключаем в
заголовочной части документа. Следовательно, прежде чем регистрировать
обработчики нажатия различных кнопок, необходимо сначала дождаться
полной загрузки страницы, чтобы браузер «увидел» эти кнопки. Значит, самым
первым, «главным» обработчиком должен быть следующий:
addEventListener("load", function()
{
...
});

После загрузки документа в окно браузера можно регистрировать все
остальные обработчики:
96

addEventListener("load", function()
{
Регистрация обработчика 1
Регистрация обработчика 2
...
Регистрация обработчика N
});

Обычно сами функции, выполняющие роли обработчиков, располагают
вне блока:
addEventListener("load", function()
{
...
});

Однако из соображений упрощения кода автор поместил внутрь этого
блока не только инструкции по регистрации обработчиков, но и функции,
обрабатывающие события. Это несколько сокращает программы и
одновременно улучшает их читабельность. Таким образом, у нас получается
главная функция, в которую вложены все остальные.
Отступление от темы
Анализатор браузера при загрузке документа считывает его «сверху вниз».
Поэтому, если сценарий располагается или загружается в головной части
документа, будет ошибкой пытаться сразу (напрямую) зарегистрировать
обработчики, например для нажатия кнопок. Ведь эти обработчики webобозреватель найдет еще до того, как будет построена объектная модель
документа. То есть браузер еще не видит кнопок, а мы уже пытаемся
привязать к ним событие click. В итоге обработчики не будут
зарегистрированы.
Чтобы избежать таких неприятностей, автор советует поступать
следующим образом: регистрировать сначала обработчик уровня окна
браузера для события load, а уже внутри него записывать остальные
обработчики (можно, в отличие от нашего случая, все функции вынести за
пределы обработчика загрузки страницы).
9.2. Выбор загружаемой страницы
По умолчанию при запуске того или иного редактора в нем оказывается
главная страница, рассказывающая о галактиках. Чтобы загрузить другую
страницу, необходимо открыть выпадающий список и щелкнуть на имени
файла. В этот момент происходит событие выбора — change. К нему привязан
обработчик, роль которого выполняет анонимная функция:
document.getElementById("sel").
addEventListener("change", function()
{
97

...
});

В ней всего два оператора. Первый присваивает переменной a текущее
значение из выпадающего списка
let a=document.getElementById("sel").value;

а второй загружает в браузер выбранную страницу, присваивая свойству
location новый адрес
window.location="редакторN.php?a="+a;

где:
– редакторN.php — имя PHP-файла редактора с номером N;
– a (следующее после разделителя ?) — параметр, который содержит адрес
страницы.
Можно было обойтись и одной строкой, сразу присваивая свойству
location адрес файла, а параметру a — значение из выпадающего списка sel. Но
запись в две строки более читабельна.
Вот как выглядит код, например, в первом редакторе:
document.getElementById("sel").
addEventListener("change", function()
{
let a=document.getElementById("sel").value;
window.location="editor1.php?a="+a;
});

Для всех остальных редакторов функция выбора страницы точно такая
же, за исключением имени PHP-файла. Имя должно быть editor2.php у второго
редактора, editor4.php — у четвертого. Только в третьем редакторе адрес
представляет собой более сложную конструкцию. Но об этом — в главе 12.
9.3. Взаимодействие
редакторов

области

контента,

WYSIWYG

и

текстового

Во всех сценариях различные функции неоднократно обращаются к
области контента загруженной во фрейм страницы, а также к окнам
визуального и текстового редакторов. Поэтому для сокращения кода мы в
самом начале создадим ссылки на эти окна.
Разберемся, как это делается на примере редактора № 1. В нем есть два
фрейма. Первый служит окном визуального представления, а во второй
загружается текущая страница. Соответственно эти фреймы имеют индексы 0 и
1. Сначала запишем ссылку на слой div с основным содержанием:
let co=frames[1].document.getElementById("cont");
98

затем на фрейм визуального редактора
let ed=frames[0].document;

и последней будет ссылка на текстовое поле:
let te=document.getElementById("tex");

Теперь передадим код из области контента в область визуального
редактирования
ed.body.innerHTML=co.innerHTML;

а затем из области редактирования в текстовое поле:
te.value=ed.body.innerHTML;

Редакторы устроены так, что любое действие в окне визуального
представления тут же передается во фрейм со страницей, а точнее, в ее слой div
с основным содержанием. Сделано так, чтобы администратор в любой момент
видел, как меняется облик редактируемой страницы. Для этого обрабатываются
два события: щелчок мышью в окне визуального представления
ed.addEventListener("click", tran);

и нажатие любой кнопки на клавиатуре
ed.addEventListener("keyup", function(ev)
{
tran();
...
// Код, который будет пояснен в разделе 9.7
});

Как видите, в обоих случаях запускается функция tran. Ее задача —
отправить данные в слой с основным содержанием:
function tran()
{
co.innerHTML=ed.body.innerHTML;
}

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

let wys=document.getElementById("wys").style;

на стили кнопки HTML-редактора
let htm=document.getElementById("htm").style;

на стили текстового поля
let tex=document.getElementById("tex").style;

на кнопку записи
let rec=document.getElementById("rec");

Первая из функций запускается, когда администратор переключается с
визуального на HTML-редактор:
document.getElementById("htm").
addEventListener("click", function()
{
...
});

Сначала происходит изменение цвета фона вкладки с надписью «WYSIWYG»
wys.background="#0000CC";

и цвета текста:
wys.color="#FFFFFF";

Затем аналогичные операции выполняются для вкладки с текстом «HTML»:
htm.background="#FFFFFF";
htm.color="#000000";

Вкладка «WYSIWYG» станет синей с белыми буквами, вкладка «HTML» —
белой с черными буквами.
Следом передаем информацию из окна визуального представления в
текстовое поле
te.value=ed.body.innerHTML;

и делаем его видимым:
tex.visibility="visible";

100

За счет того, что z-index текстового поля выше, чем у окна визуального
представления, текстовое поле оказывается наверху, а визуальное окно
скрывается.
Мы условились, что в текстовом режиме отправка данных серверной
программе невозможна. Поэтому деактивируем кнопку «Записать», установив
ей атрибут disabled:
rec.setAttribute("disabled", true);

А чтобы подчеркнуть отключение кнопки, делаем ее полупрозрачной:
rec.style.opacity=0.2;

При обратном переключении вкладок запускается вторая функция:
document.getElementById("wys").
addEventListener("click", function()
{
...
});

Первым делом вкладкам «WYSIWYG» и «HTML» возвращаются их
первоначальные цвета:
wys.background="#FFFFFF";
wys.color="#000000";
htm.background="#0000CC";
htm.color="#FFFFFF";

Теперь передаем код из текстового поля в окно визуального представления
ed.body.innerHTML=te.value;

а из него — в область основного контента страницы:
co.innerHTML=ed.body.innerHTML;

То есть при обратном переключении вкладок результаты действий
администратора в текстовом поле тоже становятся видны на странице сайта,
загруженной во фрейм.
Осталось скрыть текстовое поле
tex.visibility="hidden";

вернуть кнопке исходный уровень непрозрачности
rec.style.opacity=1;

и активировать ее, удалив атрибут disabled:
101

rec.removeAttribute("disabled");

На этом перечень взаимодействий области контента, визуального и
текстового редакторов завершен.
9.4. Фиксация в памяти выделенного фрагмента
Прежде, чем вносить изменения в контент, необходимо выделить какойлибо фрагмент текста или установить курсор в нужную позицию в окне
визуального редактирования. После этого в памяти компьютера создается
объект Selection, который хранит выделенный текст, а также начальную и
конечную позиции курсора (если курсор просто вставлен в текст, то начальные
и конечные точки совпадают).
В редакторах № 2–4 этот процесс описывается так:
let sel=document.getSelection();

В редакторе № 1 чуть иначе, поскольку фрейм представляет собой иной
документ, нежели страница редактора:
let sel=ed.getSelection();

Когда выделенная область создана, ее можно обрамлять различными
тегами, а также вставлять любые элементы, предусмотренные на главной
панели редактора.
9.5. Открытие и закрытие вкладок с настройками
Уже упоминалось, что кнопки сложного редактирования относятся к
стилевому классу swit (к этому же классу относится и кнопка «Выбрать»,
открывающая вкладку с перечнем изображений в папке cosmos). Данный
фактор используется в универсальной функции открытия вкладок с
настройками элементов.
На первом этапе мы получаем массив всех кнопок, относящихся к
упомянутому классу:
let s=document.querySelectorAll(".swit");

А затем в цикле регистрируем список обработчиков нажатия этих кнопок:
for(let i=0; i

Поскольку значение идентификатора $ide пока еще равно 0, вход не
осуществлен и поле выводится на страницу (когда переменная $ide равна
единице, вход состоялся и форму показывать не надо).
Разберем приведенный выше фрагмент. Если параметр d существует
if(isset($_GET["d"]))

получаем его значение
$dm=$_GET["d"];

и сравниваем с требуемым
if($dm=="admin")

В случае удачного сравнения печатаем форму с полем для ввода пароля:
142

echo '
';

После ввода пароля и нажатия клавиши «Enter» выполняем проверку, был
ли введен пароль и правильный ли он:
if(isset($_POST["pr"]))
{
$pr=$_POST["pr"];
if($pr=="admin")
$ide=1;
}

В случае успешной проверки меняем значение идентификатора $ide на 1.
Дальше следует ряд процедур, в которых проверяется значение
идентификатора и подключаются необходимые компоненты к сайту, чтобы
преобразовать его в редактор.
В заголовочную часть документа вписываем meta-тег, запрещающий
индексирование страниц редактора и переход по их ссылкам:


Загружаем таблицу стилей и файл сценариев редактора:

...


Наконец, последний этап — подключение файла редактора к телу
документа:


Файл editor3.php содержит такой же набор компонентов, как и остальные
редакторы, за исключением окна визуального представления контента.
143

Фактически,
editor3.php

это
содержимое
контейнера
... из других редакторов. Правда, в креативном редакторе
этот контейнер назван basis3 (чтобы отличать его от контейнера basis сайта).
12.2. Включение режима редактирования
Еще один важный момент. При загрузке редактора необходимо добавить
атрибут contenteditable слою div с основным содержанием. Делается это в
файле editor3.js следующим образом:
ed.setAttribute("contenteditable", true);

12.3. Открытие и закрытие HTML-редактора
Как вы помните, обращение к различным окнам редакторов происходит
достаточно часто. Поэтому мы неоднократно применяли сокращения в виде
ссылок. Поступим аналогичным образом и в этот раз.
Создадим сокращенную запись для текстового редактора:
let te=document.getElementById("tex");

Добавим ссылку на стили текстового поля:
let tex=document.getElementById("tex").style;

Объявим переменную, которая будет выступать в роли идентификатора
открытия текстового поля:
let cou=1;

В анонимной функции
document.getElementById("htm").
addEventListener("click", function()
{
...
})

управляющей открытием и закрытием текстового редактора, два блока. Первый
запускается, когда текстовое поле скрыто, идентификатор имеет значение 1 и
мы нажали кнопку «ОТКРЫТЬ HTML-КОД»:
if(cou==1)
{
...
}

144

Начальная операция этого блока — передача HTML-кода из слоя cont в
текстовую область:
te.value=ed.innerHTML;

Вторая операция — открытие текстового поля:
tex.visibility="visible";

Следующие две операции в точности повторяют аналогичные инструкции из
предыдущих редакторов — делаем кнопку записи неактивной и полупрозрачной:
rec.style.opacity=0.2;
rec.setAttribute("disabled", true);

Теперь выводим на кнопку HTML-редактора новый текст
document.getElementById("htm").innerHTML=
"СКРЫТЬ HTML-КОД";

и меняем значение идентификатора:
cou=2;
Чтобы скрыть вкладку HTML-кода, снова нажмем на кнопку «СКРЫТЬ
HTML-КОД». После этого начнутся обратные процессы:
– данные из текстового поля поступят в контейнер основного содержимого
страницы
ed.innerHTML=te.value;

– вкладка текстового редактора скроется
tex.visibility="hidden";

– кнопка записи снова вернется в рабочее состояние
rec.style.opacity=1;
rec.removeAttribute("disabled");

– на вкладке появится исходный текст
document.getElementById("htm").innerHTML=
"ОТКРЫТЬ HTML-КОД";

– идентификатор опять получит значение 1
cou=1;
145

12.4. Взаимодействие HTML-редактора и области контента
Вообще, по очередности эти операции более ранние, нежели изложенные
в разделе 12.3. Но описывать рабочие процессы удобнее в порядке,
определенном в оглавлении.
Как и в предыдущем разделе, создадим сокращенную запись — теперь
для области редактирования (она же область основного содержания в странице)
let ed=document.getElementById("cont");

и передадим исходные данные в текстовое поле:
te.value=ed.innerHTML;

Поскольку отдельной вкладки визуального редактирования у нас сейчас
нет, то из третьего редактора выпала функция tran (inter осталась).
Напомню, что кроме обмена информацией при загрузке системы данные
также передаются между областью контента и текстовым полемпри
открытии/закрытии HTML-редактора (как мы это видели в предыдущем
разделе).
12.5. Копирование текста
Функция копирования текста третьего редактора аналогична той, что мы
видели во втором редакторе. Нет абсолютно никаких различий.
12.6. Удаление форматирования и ссылок
У этого модуля единственное отличие от того, что мы видели во втором
редакторе, — отсутствие вызова функции tran за неимением последней.
12.7. Простое редактирование текста
Здесь те же самые массивы mid и mco с идентификаторами кнопок
простого редактирования и списком тегов для оформления текста. Точно так же
в цикле регистрируется обработчик нажатия кнопок. В функции emb опять
единственное отличие — отсутствие вызова функции tran. Думаю, что дальше
не имеет смысла без конца указывать на эту разницу. Просто помните о ней.
12.8. Изменение цвета букв или фона текста
Этот блок кода имеет некоторые фрагменты, общие как с первым
редактором, так и со вторым.
Обработчик регистрируется так же, как и в первом редакторе, с теми же
аргументами:
146

document.getElementById("col").
addEventListener("click", clr.bind(null, ""));
document.getElementById("backgr").
addEventListener("click",
clr.bind(null, "background-"));

Установка фокуса
ed.focus();

и создание элемента span
let elm=document.createElement("span");

идентичны аналогичному коду второго редактора.
12.9. Добавление разметки маркированного списка
Код добавления маркированного списка в третьем редакторе аналогичен
тому, что мы видели во втором.
12.10. Вставка линии
Код вставки линии до мельчайших подробностей совпадает с тем, что
написан для аналогичного блока редактора № 1.
Функция place имеет отличие от такой же функции редактора № 2 всего в
одном пункте — вместо набора классов добавляется набор свойств стиля:
elm.style=z;

12.11. Вставка фрейма
Модуль добавления фрейма в третьем редакторе — один в один такой же
модуль из первого редактора.
12.12. Вставка рисунка
Блок вставки изображения в третьем редакторе — точно такой же, как и в
первом редакторе.
12.13. Вставка таблицы
Функция вставки таблицы третьего редактора отличается от этой же
функции первого тремя компонентами:

147

– наличием фокусировки области основного содержания
ed.focus();

– созданием таблицы в текущем документе
let elm=document.createElement("table");

– отсутствием вызова функции tran.
12.14. Вставка символов
Регистрация обработчиков для кнопок с символами во всех уже
рассмотренных редакторах одинаковая.
Функция вставки символов третьего редактора имеет отличия от функции
sign первого редактора по тем же трем пунктам, что были упомянуты в
разделе 12.13:
– наличию фокусировки области основного содержания;
– созданию текстового узла в текущем документе;
– отсутствию вызова функции tran.
12.15. Добавление ссылки
Опять те же три отличия от соответствующего блока кода первого
редактора. По всем остальным пунктам — полное совпадение.
12.16. Добавление заголовка
Полная аналогия с анонимной функцией добавления заголовка редактора
№ 1. В функции wrap — три уже ставших привычными отличия.
12.17. Выравнивание абзаца
Полная идентичность с такой же функцией первого редактора.
12.18. Настройка шрифта
Опять все то же самое, что и в первом редакторе.
12.19. Перемещение панели
Модуль перемещения главной панели в файле editor3.js расположен в
самом начале. Но поскольку его роль второстепенна, мы рассматриваем эту
часть кода в последнюю очередь.
Для выполнения необходимых манипуляций зарегистрируем сначала два
обработчика:
148

– нажатия кнопки мыши на контейнере с панелью
addEventListener("load", function()
{
document.getElementById("basis3").
addEventListener("mousedown", coor);
});

– отпускания кнопки мыши в любой точке окна браузера
addEventListener("mouseup", stco);

Введем переменную, предназначенную для хранения значения
разности между точкой клика на панели и вертикальной координатой
верхнего края панели (тем самым мы определяем, на каком расстоянии от
указателя все время должен находиться верхний край панели в процессе
движения):
let dv=0;

Этот параметр необходим, чтобы при перемещении панели она двигалась
равномерно, а указатель мыши все время находился в одной и той же точке
панели.
Напишем функцию coor, которая запускается после нажатия кнопки
мыши на панели:
function coor()
{
...
}

Первая операция — определение вертикальной координаты указателя:
let v=event.pageY;

Следом узнаем координаты верхнего левого угла панели:
let sv=document.getElementById("basis3").offsetTop;

Вычисляем разницу (рис. 12.19.1)
dv=v-sv;

и регистрируем обработчик для события перемещения мыши по странице:
addEventListener("mousemove", neco);

149

Рис. 12.19.1. Вычисление начального смещения панели относительно верхней границы окна
браузера

Как только мы начинаем перемещать панель, запускается функция neco:
function neco()
{
...
}

В ней сначала вычисляется новая вертикальная координата указателя
let nv=event.pageY;

потом из значения новой координаты nv вычитается значение переменной dv с
уже вычисленным начальным смещением
let fv=nv-dv;

и тем самым мы получаем новое значение координаты, в которой должен
оказаться верхний край панели. Перемещаем панель в эту точку:
document.getElementById("basis3").style.top=fv+"px";

Повторные вычисления текущих координат и смещение панели в новое
положение продолжаются до тех пор, пока мы перемещаем мышь и пока
нажата ее левая кнопка. Как только мы отпускаем кнопку, «срабатывает»
функция, в которой всего одна инструкция — удалить обработчик события
перемещения мыши:
function stco()
{
removeEventListener("mousemove", neco);
}

Движение панели прекратится, и она займет новое положение, то, которое
наиболее удобно администратору при редактировании контента.
150

Отступление от темы
Автор видел много визуальных редакторов, но с перемещающейся панелью —
ни разу. Если такие все же существуют, значит, мне не удалось охватить
своим вниманием все разнообразие WYSIWYG-систем. Если же визуальных
редакторов с перемещающейся панелью раньше не было, то мне будет
приятно внести скромную лепту новизны в развитие CMS.

151

13. Ретро-редактор
Вопрос: если первые три редактора, как мы убедились, вполне успешно
выполняют свои функции, стоит ли изучать редактор, построенный на
использовании ретро-метода execCommand? Мой ответ — стоит.
Хочу напомнить, что такая система имеет ряд преимуществ. Повторим их:
– метод продолжает работать в требуемых нам объемах во всех браузерах;
– execCommand до сих пор используется во многих визуальных
редакторах (а значит, не одни мы доверяем этому методу);
– благодаря тому, что большинство команд метода унифицированы,
редакторы на его основе занимают меньше всего места в памяти компьютера;
– написать редактор на основе execCommand гораздо легче — в такой
системе будут более лаконичные и простые функции;
– нет полной уверенности, что на этом методе окончательно поставлено
клеймо устаревшего.
Есть и другие преимущества. Например, в редакторах № 1–3, добавляя
элемент — таблицу или рисунок, мы в обязательном порядке сначала
устанавливали фокус окна визуального представления. Помните, почему?
Потому что иначе, забыв установить курсор в окне, мы тем самым помещаем
элемент не в окно, а в панель настроек, так как в этом случае в момент нажатия
кнопки «Вставить» именно панель будет находиться в фокусе. В ретроредакторе устанавливать фокус не надо. Забыли вставить курсор в окно
визуального представления — элемент просто не будет создан.
Или еще один момент. В разделе 8.14 мы говорили, что для удаления
ссылки или форматирования необходимо выделить в тексте справа и слева на
один символ больше. В ретро-редакторе таких сложностей нет — надо
выделять только необходимый текст без дополнительных символов по краям.
Наконец, редактор с execCommand, в отличие от предыдущих трех, при
удалении форматирования сохраняет в тексте все HTML-теги, которые не
имеют отношения к форматированию.
Так что мой совет — попробовать, поэкспериментировать.
Перечень компонентов редактора:
– основной файл — editor4.php;
– файл сценариев на JavaScript — set/editor4.js;
– файл таблицы стилей — set/editor4.css.
Демонстрационная страница редактора: https://editjs.ru/editor4.php?a=
index. Зайдя на нее, вы увидите, что мы опять вернулись к традиционному
построению редактора в виде отдельной страницы.
13.1. Установка режима редактирования
Режим редактирования в данной системе устанавливается так же, как это
делалось во втором редакторе:

152

13.2. Простое редактирование текста
Смена метода форматирования текста и вставки элементов привела к
тому, что в этом блоке появились заметные изменения.
Теперь функция простого редактирования обслуживает следующие
кнопки:

копирование фрагмента;

удаление форматирования;

преобразование в маркированный список;

удаление ссылки.
По-прежнему относятся к блоку простого редактирования, как и в других
редакторах, шесть кнопок: выделение жирным, курсивом, подчеркиванием,
зачеркиванием, а также преобразование текста в надстрочный и подстрочный.
В результате расширился список элементов массива mid — их 10:
let mid=["cop", "forma", "ulli", "delin", "bol",
"ital", "under", "strik", "sup", "sub"];

Массив mco не только увеличился. Теперь его элементы хранят совершенно
иные значения — команды метода execCommand, необходимые для
выполнения копирования и преобразования текста:
let mco=["Copy", "RemoveFormat",
"InsertUnorderedList", "Unlink", "Bold",
"Italic", "Underline", "strikeThrough",
"superscript", "subscript"];

Ниже приведена таблица 13.2.1 с расшифровкой команд:
Таблица 13.2.1

Метод execCommand
Команда
Copy

Описание
Выполняет копирование выделенного фрагмента,
включая текст, его форматирование и различные
элементы
RemoveFormat
Удаляет форматирование из выделенного текста. Не
затрагивает находящиеся в тексте элементы
InsertUnorderedList Преобразует выделенный фрагмент в маркированный
список
Unlink
Удаляет выделенную ссылку, оставляя образующий ее
текст
Bold
Добавляет/удаляет выделение жирным
Italic
Добавляет/удаляет выделение курсивом
Underline
Добавляет/удаляет выделение подчеркиванием
strikeThrough
Добавляет/удаляет выделение зачеркиванием
153

Продолжение табл.

Команда
superscript
subscript

Добавляет/удаляет
фрагмента
Добавляет/удаляет
фрагмента

Описание
верхний индекс

у

выделенного

нижний

у

выделенного

индекс

У последних шести команд есть свои особенности. Рассмотрим их на
конкретном примере. Если выделить слово, набранное обычным шрифтом, и
нажать кнопку «Bold», то буквы станут «жирными». Если выделить «жирное»
слово и нажать кнопку «Bold», то начертание букв вернется к обычному виду.
Остальные пять кнопок из упомянутой шестерки команд действуют по
аналогичной схеме. На взгляд автора, это очень удобно при оформлении текста.
Регистрация обработчика для перечисленных выше кнопок происходит
так же, как и в остальных редакторах.
Функция emb сохранила проверку выделения
if(sel=="")
alert("Вы не выделили текст!");

но при этом стала короче. Теперь в ней всего одна команда форматирования
текста:
document.execCommand(v);

Обратите внимание! Поскольку окно редактирования у нас является
компонентом текущего документа, то и метод работает с объектом document.
Завершается процесс стандартным вызовом двух функций:
tran();
inter();

Еще один важный момент. По сравнению с редакторами № 2 и 3 в этой
функции отсутствует фокусировка. Более того, ее нет ни в одной другой
функции четвертого редактора. Метод execCommand не требует концентрации
внимания на окне редактирования. Если вы забыли выделить текст, то его
форматирование не произойдет. Если вы не вставили курсор, то элемент —
таблица, рисунок, линия — не будет создан вообще. execCommand работает
только при наличии выделения (или установленного курсора) в окнах, у
которых есть атрибут contentEditable или включено свойство designMode.
Теперь обратим внимание на самую первую команду Copy. С ее
помощью в выделенном фрагменте копируется текст и различные элементы. Но
тот же самый результат можно получить, выделив фрагмент, щелкнув на нем
правой кнопкой мыши и выбрав из контекстного меню пункт «Копировать».
А это значит, что совершенно безболезненно можно отказаться от команды
Copy и сохранить возможность копировать «чистый» текст без HTML154

элементов (как в других редакторах). В этом случае в массивах mid и mco
нужно удалить элементы с индексом 0, а кнопке
назначить точно такой же
обработчик, как, например, во втором редакторе.
13.3. Изменение цвета букв или фона текста
Регистрация обработчика нажатия кнопок цветового оформления такая
же, как в редакторах 1 и 3.
Запуская функцию clr, в обязательном порядке проверяем выделение.
В остальном данная функция мало напоминает то, что мы видели раньше.
Здесь мы используем команду insertHTML метода execCommand. Таким
способом можно вставить блок HTML-кода, отдельный элемент или простой
текст. Для выполнения данной команды методу требуется передать три
аргумента: имя команды; значение, указывающее, отображать или нет
пользовательский интерфейс; HTML-код или текст. Второй аргумент обычно
указывают false. Это означает, что третий аргумент передается в метод
непосредственно из программы.
На первом этапе определимся с третьим аргументом. Он представляет
собой выделенный текст, обрамленный открывающим и закрывающим тегами
span. Стилевое оформление «внутренностей» тега мы получаем из панели
выбора цвета:
document.getElementById("ccc").value

Полный код, формирующий третий аргумент:
let cl=''
+sel+'';

Напоминание. Если аргумент b, переданный в функцию clr, пустой, то
цветом выделяется текст. Если значение этого аргумента background-, то
меняется цвет фона текста. sel — объект, содержащий выделенный текст.
На втором шаге создаем цветовое оформление:
document.execCommand("insertHTML", false, cl);

Завершается процесс вызовом функций tran и inter.
13.4. Вставка линии
До 17 строки функция вставки линии похожа на то, что мы видели,
например, в первом редакторе. Но дальше начинаются отличия. В файле
editor4.js при создании какого-либо элемента используется команда
insertHTML. Поэтому сейчас наша задача — сформировать не просто набор
155

свойств элемента, а его полный код. Делаем это в два приема. Сначала
формируем стили
let shr=' style="'+hr1+hr2+'background: '+hr3_v+
'; border: 0;"';

а потом компонуем линию:
let hrres='';

Теперь можно отправлять данные функции place:
place(hrres, "hr_d");

В новой версии она принимает только два аргумента: HTML-код создаваемого
элемента и id закрываемой вкладки:
function place(x, y)
{
...
}

«Начинка» функции place состоит из четырех инструкций. Первая создает
в окне редактора новый элемент:
document.execCommand("insertHTML", false, x);

Назначение остальных вам уже известно:
tran();
inter();
clo(y);

13.5. Вставка фрейма
Функция отличается от аналогичных тремя последними строками:
– составляем набор свойств фрейма
let sifr=' style="'+ifr2+ifr3+ifr4+ifr5+ifr7+'"';

– «собираем» его HTML-код
let ifres='
';

– поручаем функции place создание фрейма
place(ifres, "ifr_d");

156

13.6. Вставка рисунка
Такая же картина вырисовывается при создании изображения:
– составляем набор свойств картинки
let sima='style="'+ima4+ima5+'width: '+ima6+
'; border: '+ima7+' solid '
+ima8_v+'; cursor: pointer;"';

– пишем ее HTML-код
let imares='';

– вызываем функцию place для вставки рисунка
place(imares, "img_d");

13.7. Вставка таблицы
После выяснения, какие настройки введены для создания таблицы,
начинаем создавать первую часть ее HTML-кода:
let tb='';

Затем наполняем таблицу ячейками:
let sum="";
for(let i=0; i