WYSIWYG: вставляем произвольный HTML-код
Задача: при редактировании данных в визуальном редакторе иметь возможность вставлять произвольные элементы форматирования, например, заголовки.
Метод execCommand позволяет вставлять как простейшие элементы форматирования (жирность, курсив, подчеркивание), так и более сложные. Начнем с них.
Диалог с пользователем — создаем ссылки
Усложним код нашего простейшего висивига, добавив туда кнопку для добавления ссылок. Прежде чем добавить ссылку, необходимо спросить у пользователя её URL. Сделаем это с помощью метода prompt. Всего несколько строк кода необходимо добавить к текущему коду висивига, чтобы заработало добавление ссылок:
document.write("<input type='button' value='Link' onclick='setLink()' class='under' />");
// Запишем код функции для выставления форматирования
// Используется метод execCommand объекта document
function setLink() {
var url = prompt("Введите URL:", "http://");
if (!url) return;
iWin.focus();
iWin.document.execCommand("CreateLink", null, url);
}
Пример простейшего ВИСИВИГа с функцией добавления ссылок
Как видно из примера, метод execCommand принимает в качестве третьего аргумента параметр команды CreateLink — URL ссылки. Не только создание ссылки требует диалога с пользователем. Чтобы задать цвет текста или цвет фона (команды ForeColor и BackColor соот-но), необходимо попросить юзера выбрать этот цвет (обычно из какого-то списка), а затем передать его методу в формате #RRGGBB.
Вставляем произвольный HTML-контент
Вам необходимо вставить в визуальный редактор вполне конкретный HTML-код, например такой:
Метод execCommand бессилен для решении такой задачи. Необходимо собственное решение, например, такой обходной путь:
- Чтобы поставить произвольное форматирование на выделенный фрагмент, воспользуемся командой forecolor, которая выставит цвет текста. Цвет специально подберем такой, которым пользуются нечасто.
- В зависимости от браузера цвет выставляется либо с помощью <font color="#RRGGBB"></font> (IE, Opera), либо с помощью <span style="color:rgb(RR,GG,BB)"></span> (Gecko). Чтобы привести цвет к единому формату #RRGGBB воспользуемся функцией rgbNormal().
- Пройдемся по всем узлам DOM-дерева документа, найдем фонты и спаны с нужным цветом и добавим в них необходимый HTML-код, не забывая почистить за собой. Обход по узлам — дело не простое. Т.к. мы удаляем узлы с нужным цветом, необходимо идти от самых вложенных элементов вверх по иерархии узлов, чтобы не получилось сбоя. Для этого восопользуемся функцией nodeList, которая отдаст массив узлов с указанием степени их вложенности, который можно отсортировать.
Новый код:
// ШАГ 5: Форматирование произвольным HTML-контентом
// ***********************
// nodeList - формирует массив всех узлов с указанием степени их вложенности
function nodeList(parentNode, list, level) {
var i, node, count;
if (!list) list = new Array();
level++;
for (i = 0; i < parentNode.childNodes.length; i++) {
node = parentNode.childNodes[i];
if (node.nodeType != 1) continue;
count = list.length;
list[count] = new Array();
list[count][0] = node;
list[count][1] = level;
nodeList(node, list, level);
}
return list;
}
// rgbNormal - приводит цвет к стандарту #RRGGBB
function rgbNormal(color) {
color = color.toString();
var re = /rgb\((.*?)\)/i;
if(re.test(color)) {
compose = RegExp.$1.split(",");
var hex = ['0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'];
var result = "#";
for (var i = 0; i < compose.length; i++) {
rgb = parseInt(compose[i]);
result += hex[parseInt(rgb / 16)] + hex[rgb % 16];
}
return result;
} else return color;
}
function execCommandImitation(start, end) {
// Cтавим ForeColor-форматирование с помощью специального цвета
iDoc.execCommand("ForeColor", false, "#f5F856");
// Получаем все элементы форматируемого документа
var allNodes = nodeList(iDoc.body, false, 0);
// Сортируем их по уровню вложенности
var maxLevel = 0;
for (i = 0; i < allNodes.length; i++) {
maxLevel = allNodes[i][1] > maxLevel ? allNodes[i][1] : maxLevel;
}
// 4. Для всех элементов заменяем FONT и SPAN со специальным цветом на переданный код
var node, newnode, color, parent;
for (j = maxLevel; j >= 1; j--) {
for (i = 0; i < allNodes.length; i++) {
if (allNodes[i][1] != j) continue;
node = allNodes[i][0];
sname = node.nodeName.toLowerCase();
color = node.color ? rgbNormal(node.color) : rgbNormal(node.style.color);
if (color) color = color.toLowerCase();
if (sname == "font" || sname == "span" && color == "#f5f856") {
try {
node.innerHTML = start + node.innerHTML + end;
} catch(e) {}
parent = node.parentNode;
while (node.childNodes.length > 0) parent.insertBefore(node.firstChild, node);
parent.removeChild(node);
}
}
}
iWin.focus();
}
Пример ВИСИВИГа c произвольным HTML-форматированием
Чтобы заголовок был оранжевым, при формировании стилей документа был добавлен класс:
Поверено в WIN: IE6, IE7, FF2, Opera 9.5, Safari 3.
Задача решена!
// Все права на статью JavaScript::WYSIWYG - вставляем произвольный HTML-код принадлежат сайту 2007.fastcoder.ru