Как создать встроенный текстовый редактор с помощью атрибута contentEditable

Как создать встроенный текстовый редактор с помощью атрибута contentEditable

От автора: Создание встроенного текстового редактора требует определенных усилий. Начать можно с переключения элемента в режим редактирования с помощью полей input или textarea. Чтобы переключение было плавным вам придется придать элементам одинаковые стили. После того, как пользователь закончил редактирование, необходимо заменить весь текст и опять переключить элементы. Атрибут contentEditable сильно облегчает эту задачу.

Необходимо лишь задать этому атрибуту значение true, и HTML5 теги можно будет редактировать. В этом уроке с помощью данного атрибута мы создадим редактор форматированного текста.

Основы

Атрибут принимает три возможных значения: true, false и inherit. True означает, что элемент можно редактировать. Пустое значение также расценивается, как true. False говорит о том, что элемент нельзя редактировать. По умолчанию задано значение inherit, которое означает, что элемент можно отредактировать в том случае, если его ближайший родительский контейнер также можно отредактировать. Это означает, что если сделать элемент редактируемым, то и все его дочерние элементы, в том числе и не ближайшие, будут также редактируемыми. Исключение составляют дочерние элементы, у которых задано contentEditable = false.

Значения можно изменять динамически с помощью JavaScript. Если задать некорректное значение, выскочит исключение SyntaxError.

Создаем редактор

Чтобы создать встроенный редактор, нужно уметь изменять значение атрибута contentEditable в любое время.
Во время переключения атрибута contentEditable необходимо знать, какое значение он хранит на данный момент. Для этого можно воспользоваться свойством isContentEditable. Если isContentEditable возвращает true, элемент находится в режиме редактирования и наоборот. Чуть ниже мы будем с помощью этого свойства определять состояние нескольких элементов в документе.

Сначала необходимо создать кнопку переключения в режим редактирования и сам текст.

<button id="editBtn" type="button">Edit Document</button>
 
<div id="editor">
    <h1 id="title">A Nice Heading.</h1>
    <p>Last Edited By - <span id="author">Monty Shokeen</span></p>
    <p id="content">Some content that needs correction.</p>
</div>

Все элементы, которые будут редактироваться, должны иметь свой уникальный id. Идентификаторы помогут нам при сохранении изменений, или когда нам потребуется сохранить текст для дальнейшей его замены в каждом элементе. Код JS ниже редактирует и сохраняет изменения.

var editBtn = document.getElementById('editBtn');
var editables = document.querySelectorAll('#title, #author, #content')
 
editBtn.addEventListener('click', function(e) {
  if (!editables[0].isContentEditable) {
    editables[0].contentEditable = 'true';
    editables[1].contentEditable = 'true';
    editables[2].contentEditable = 'true';
    editBtn.innerHTML = 'Save Changes';
    editBtn.style.backgroundColor = '#6F9';
  } else {
    // выключаем режим редактирования
    editables[0].contentEditable = 'false';
    editables[1].contentEditable = 'false';
    editables[2].contentEditable = 'false';
    // изменяем текст и цвет кнопки
    editBtn.innerHTML = 'Enable Editing';
    editBtn.style.backgroundColor = '#F96';
    // сохраняем данные в localStorage 
    for (var i = 0; i < editables.length; i++) {
      localStorage.setItem(editables.getAttribute('id'), editables.innerHTML);
    }
  }
});

Для хранения отредактированного текста в переменной можно воспользоваться querySelectorAll(). Данный метод возвращает NodeList, в котором хранятся все элементы документа, заданные по определенному селектору. С помощью данного метода намного легче отслеживать редактируемые элементы в одной переменной. К примеру, получить доступ к заголовку документа можно с помощью editables[0], что мы сейчас и сделаем.

Теперь необходимо привязать к событию клика по кнопке обработчик. Во время каждого клика по кнопке пользователем мы проверяем заголовок на режим редактирования. Если заголовок нельзя редактировать, всем редактируемым элементам мы задаем свойство contentEditable в true. А текст кнопки ‘Edit Document’ меняем на ‘Save Changes’. После того, как пользователь внес необходимые изменения, он кликает на кнопку ‘Save Changes’, что приводит к моментальному сохранению изменений.

Если заголовок редактируется, всем элементам задается свойство contentEditable в false. На данном этапе мы может сохранять контент документа на сервере, чтобы воспользоваться им позже, а можем синхронизировать изменения с копией документа. В этом уроке я все буду сохранять в localStorage. Чтобы случайно не перезаписать данные при сохранении в localStorage, я использую id каждого элемента. CodePen демо

Получение сохраненного контента

Если вы в демо выше внесете какие-либо изменения и перезагрузите страницу, то все изменения пропадут. Это происходит потому, что не прописан код, который бы восстанавливал сохраненные данные. После сохранения данных в localStorage нам необходимо их восстановить, когда пользователь снова откроет страницу.

if (typeof(Storage) !== "undefined") {
 
  if (localStorage.getItem('title') !== null) {
    editables[0].innerHTML = localStorage.getItem('title');
  }
   
  if (localStorage.getItem('author') !== null) {
    editables[1].innerHTML = localStorage.getItem('author');
  }
   
  if (localStorage.getItem('content') !== null) {
    editables[2].innerHTML = localStorage.getItem('content');
  } 
}

В коде выше проверяется, существуют ли в localStorage данные о заголовке, авторе и контенте. Если они там есть, в innerHTML соответствующих элементов заносятся эти данные. Еще одно CodePen демо

Делаем редактор более дружелюбным

Нам нужно внести два изменения в наш редактор. Необходимо сделать так, чтобы пользователь понимал, что можно редактировать, а что нельзя. Сделать это можно, изменив стили CSS конкретных элементов: это могут быть изменения шрифта или цвета. Отобрать элементы для добавления новых стилей можно с помощью селектора [contenteditable="true"].

[contenteditable="true"] {
  font-family: "Rajdhani";
  color: #C00;
}

Второе изменение – автосохранение данных. Сделать это можно по-разному. Можно сохранять данные каждые 5 секунд.

setInterval(function() {
  for (var i = 0; i < editables.length; i++) {
    localStorage.setItem(editables.getAttribute('id'), editables.innerHTML);
  }
}, 5000);

Можно сохранять данные по каждому событию keydown.

document.addEventListener('keydown', function(e) {
  for (var i = 0; i < editables.length; i++) {
    localStorage.setItem(editables.getAttribute('id'), editables.innerHTML);
  }
});

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

Редактирование всей страницы с помощью свойства Design Mode

contentEditable полезен, когда нужно изменить несколько элементов на веб-странице. Если же вам нужно изменить все или почти все элементы на странице, то тут вам поможет свойство designMode. Данное свойство применяется ко всему документу. Для включения и отключения используются соответственно document.designMode = ‘on’; и document.designMode = ‘off’;.

Данное свойство доказало свою полезность в ситуациях, когда вы дизайнер и работаете с контент-менеджером. Вы создаете дизайн страницы и заполняете ее пробным текстом, а контент-менеджеры заменяют этот текст на нормальный. Чтобы посмотреть designMode в действии, откройте консоль в панели разработчика браузера, введите document.designMode = ‘on’; и нажмите Enter. Теперь все на странице можно редактировать.

Заключительные мысли

Атрибут contentEditable удобен в тех ситуациях, когда нужно быстро отредактировать статью или позволить пользователям быстро изменить их комментарий. Впервые данная функция была реализована в IE 5.5, позже она была стандартизирована в WHATWG. Поддержка в браузерах тоже довольно неплохая. Атрибут поддерживается во всех основных браузерах, за исключением Opera Mini.

JavaScript де-факто стал одним из языков работы в интернете. Данный язык требует тщательного изучения. Также вам могут пригодиться различные фреймворки и библиотеки. Если вы ищите дополнительные источники для изучения или хотите начать использовать данный язык в своих работах, загляните на Envato marketplace.

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

Автор: Monty Shokeen

Источник: http://code.tutsplus.com/

Редакция: Команда webformyself.

JavaScript&jQuery с нуля до профи

Пройдите пошаговый видеокурс по JavaScript&jQuery

Научиться

Метки:

Комментарии Вконтакте:

Комментарии Facebook:

Комментарии (2)

  1. evgeniyholon

    В 21 строке кода опечатка —> localStorage.setItem(editables.getAttribute('id'), editables.innerHTML);
    Вместо editables надо editables[i]

  2. evgeniyholon

    Та же самая опечатка есть и в двух последних блоках кода в строчке 3

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Я не робот.

Spam Protection by WP-SpamFree