Статьи

Создание редактора WYSIWYG с атрибутом contentEditable

Редакторы WYSIWYG довольно популярны. Вы могли бы также использовать один в какой-то момент. Есть много библиотек, которые помогут вам настроить свой собственный редактор. Хотя их можно быстро настроить, использование этих библиотек также имеет свои недостатки. Начнем с того, что они раздутые. У большинства из них есть необычные функции, которые вы можете не использовать. Более того, настройка внешнего вида этих редакторов может быть головной болью.

В этом уроке мы создадим наш собственный облегченный редактор WYSIWYG. К концу этого урока у вас будет редактор с базовыми возможностями форматирования, стилизованный под ваши предпочтения.

Начнем с введения execCommand . Мы будем использовать эту команду для широкой реализации нашего редактора.

execCommand — это метод объекта документа. Это позволяет нам манипулировать содержимым редактируемой области. При использовании вместе с contentEditable , это может помочь нам создать текстовый редактор. Доступно множество команд, таких как добавление ссылки, выделение жирным или курсивом и изменение размера или цвета шрифта. Этот метод следует синтаксису:

1
document.execCommand(CommandName, ShowDefaultUI, ValueArgument);

CommandName — это строка, которая указывает имя команды, которую нужно выполнить. ShowDefaultUI   является логическим значением, указывающим, должен ли отображаться поддерживающий интерфейс или нет. Эта опция реализована не полностью, и лучше всего установить ее в false. ValueArgument — это строка для предоставления информации, такой как URL изображения или foreColor . Этот аргумент устанавливается равным null когда команде не требуется значение для вступления в силу.

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

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

1
document.execCommand(commandName, false, null);

CommandName — это просто имя команды, например justifyCenter , justifyRight , bold и т. Д.

Команды, такие как insertImage , createLink и foreColor нуждаются в третьем аргументе для правильной работы. Для этих команд вам нужен следующий синтаксис:

1
document.execCommand(commandName, false, value);

Для insertImage значением будет URL-адрес вставляемого изображения. В случае foreColor это будет значение цвета, например #FF9966 или имя, например, blue .

Добавление тегов блочного стиля HTML требует использования formatBlock качестве commandName и имени тега в качестве valueArgument . Синтаксис будет похож на:

1
document.execCommand(‘formatBlock’, false, tagName);

Этот метод добавит тег HTML в стиле блока вокруг строки, которая содержит текущий выбор. Он также заменяет любой тег, который уже существовал там. tagName может быть любым из тегов заголовка ( h1h6 ), p или blockquote .

Я обсудил наиболее распространенные команды здесь. Вы можете посетить Mozilla для получения списка всех доступных команд.

Теперь, когда у нас нет основ, пришло время создать панель инструментов. Я буду использовать иконки Font Awesome для кнопок. Возможно, вы заметили, что, оставив в стороне несколько различий, все execCommand имеют схожую структуру. Мы можем использовать это в наших интересах, используя следующую разметку для кнопок панели инструментов:

1
<a href=»#» data-command=’commandName’><i class=’fa fa-icon’></i></a>

Таким образом, всякий раз, когда пользователи нажимают кнопку, мы можем сказать, какую версию execCommand использовать, основываясь на значении атрибута data-command . Вот несколько кнопок для справки:

1
2
3
4
5
<a href=»#» data-command=’h2′>H2</a>
<a href=»#» data-command=’undo’><i class=’fa fa-undo’></i></a>
<a href=»#» data-command=’createlink’><i class=’fa fa-link’></i></a>
<a href=»#» data-command=’justifyLeft’><i class=’fa fa-align-left’></i></a>
<a href=»#» data-command=’superscript’><i class=’fa fa-superscript’></i></a>

Значение атрибута data-command для первой кнопки — h2 . После проверки этого значения в JavaScript мы будем использовать версию execCommand метода execCommand . Точно так же для последней кнопки superscript предполагает, что нам нужно использовать версию execCommand no execCommand .

Создание foreColor и backColor — это backColor история. Они создают две проблемы. В зависимости от того, сколько цветов мы предоставляем пользователям на выбор, написание такого кода может быть утомительным и подверженным ошибкам. Чтобы решить эту проблему, мы можем использовать следующий код JavaScript:

1
2
3
4
5
6
7
var colorPalette = [‘000000’, ‘FF9966’, ‘6699FF’, ’99FF66′,’CC0000′, ’00CC00′, ‘0000CC’, ‘333333’, ‘0066FF’, ‘FFFFFF’];
                     
var forePalette = $(‘.fore-palette’);
 
for (var i = 0; i < colorPalette.length; i++) {
  forePalette.append(‘<a href=»#» data-command=»forecolor» data-value=»‘ + ‘#’ + colorPalette[i] + ‘» style=»background-color:’ + ‘#’ + colorPalette[i] + ‘;» class=»palette-item»></a>’);
}

Обратите внимание, что я также устанавливаю атрибут data-value для каждого цвета. Позже это будет использоваться как valueArgument в методе execCommand .

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

1
2
3
4
<div class=»fore-wrapper»><i class=’fa fa-font’></i>
  <div class=»fore-palette»>
  </div>
</div>

Чтобы отображать палитры только при hover , нам нужен следующий CSS:

01
02
03
04
05
06
07
08
09
10
11
.fore-palette,
.back-palette {
  display: none;
}
 
.fore-wrapper:hover .fore-palette,
.back-wrapper:hover .back-palette {
  display: block;
  float: left;
  position: absolute;
}

В демонстрации CodePen есть много других CSS-правил, чтобы сделать панель инструментов более красивой, но это все, что нужно для основной функциональности.

Теперь пришло время сделать наш редактор работоспособным. Код, необходимый для этого, удивительно мал.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
$(‘.toolbar a’).click(function(e) {
     
  var command = $(this).data(‘command’);
   
  if (command == ‘h1’ || command == ‘h2’ || command == ‘p’) {
    document.execCommand(‘formatBlock’, false, command);
  }
   
  if (command == ‘forecolor’ || command == ‘backcolor’) {
    document.execCommand($(this).data(‘command’), false, $(this).data(‘value’));
  }
   
  if (command == ‘createlink’ || command == ‘insertimage’) {
    url = prompt(‘Enter the link here: ‘,’http:\/\/’);
    document.execCommand($(this).data(‘command’), false, url);
  }
   
  else document.execCommand($(this).data(‘command’), false, null);
   
});

Мы начинаем с прикрепления события click ко всем кнопкам панели инструментов. При каждом нажатии кнопки панели инструментов мы сохраняем значение атрибута data-command соответствующей кнопки в переменной command . Позднее это используется для вызова соответствующей версии метода execCommand . Это помогает в написании краткого кода и избегает повторения.

При настройке foreColor и backColor я использую атрибут data-value в качестве третьего аргумента. createLink и insertImage не имеют постоянного значения url , поэтому мы используем подсказку для получения значений от пользователя. Вы также можете выполнить дополнительные проверки, чтобы убедиться, что url действителен. Если command переменная не удовлетворяет ни одному из блоков if , мы запускаем первую версию execCommand .

Вот так выглядит наш редактор WYSIWYG .

WYSIWYG редактор

Вы также можете реализовать функцию localStorage , используя localStorage который я обсуждал в моем предыдущем уроке.

Различные браузеры имеют небольшие различия в реализации. Например, имейте в виду, что при использовании formatBlock Internet Explorer поддерживает только теги заголовков h1 - h6 , address и pre . Вам также необходимо включить разделители тегов при указании имени commandName вроде <h3> .

Не все команды поддерживаются каждым браузером. Internet Explorer не поддерживает такие команды, как insertHTML и hiliteColor . Точно так же insertBrOnReturn поддерживается только Firefox. Вы можете прочитать больше о несоответствиях браузера на этой странице GitHub .

Создание собственного редактора WYSIWYG может стать отличным опытом обучения. В этом уроке я рассмотрел много команд и использовал немного CSS для базовых стилей. В качестве упражнения я бы предложил вам реализовать кнопку панели инструментов, чтобы установить font текста. Реализация будет аналогична кнопке foreColor .

Надеюсь, вам понравился этот урок и вы узнали что-то новое. Если вы создали свой собственный редактор WYSIWYG с нуля, не стесняйтесь ссылаться на него в разделе комментариев.