Источник: http://learn.javascript.ru/modifying-document
Изменение DOM — ключ к созданию «живых» страниц.
В этой главе мы рассмотрим, как создавать новые элементы «на лету» и заполнять их данными.
Для создания элементов используются следующие методы документа:
document.createElement(tag). Создает новый элемент с указанным тегом: var div = document.createElement('div');
document.createTextNode(text). Создает новый текстовый узел с данным текстом: var textElem = document.createTextNode('Тут был я');
Новому элементу тут же можно поставить свойства:
var newDiv = document.createElement('div');
newDiv.className = 'myclass';
newDiv.id = 'myid';
newDiv.innerHTML = 'Привет, мир!';
Новый элемент можно также склонировать из существующего:
newElem = elem.cloneNode(true)
Клонирует элемент elem, вместе с атрибутами, включая вложенные в него.
newElem = elem.cloneNode(false)
Клонирует элемент elem, вместе с атрибутами, но без подэлементов.
Чтобы DOM-узел был показан на странице, его необходимо вставить в документ.
Для этого у любого элемента есть метод appendChild:
Добавляет elem в список дочерних элементов parentElem. Новый узел добавляется в конец списка.
Следующий пример добавляет новый элемент в уже существующий div:
<div>
...
</div>
<script>
var parentElem = document.body.children[0];
var newDiv = document.createElement('div');
newDiv.innerHTML = 'Привет, мир!';
parentElem.appendChild(newDiv);
</script>
Вставляет elem в список дочерних parentElem, перед элементом nextSibling.
Сделать новый div первым дочерним можно так:
<div>
...
</div>
<script>
var parentElem = document.body.children[0];
var newDiv = document.createElement('div');
newDiv.innerHTML = 'Привет, мир!';
parentElem.insertBefore(newDiv, parentElem.firstChild);
</script>
Вместо nextSibling может быть null, тогда insertBefore работает как appendChild.
parentElem.insertBefore(elem, null);
// то же, что и:
parentElem.appendChild(elem)
Все методы вставки возвращают вставленный узел, например parent.appendChild(elem) возвращает elem.
Для удаления узла есть два метода:
Удаляет elem из списка детей parentElem.
Среди детей parentElem заменяет currentElem на elem.
Оба этих метода возвращают удаленный узел. Они просто вынимают его из списка, никто не мешает вставить его обратно в DOM в будущем.
Если вы хотите переместить элемент на новое место — не нужно его удалять со старого.
Все методы вставки автоматически удаляют вставляемый элемент со старого места.
Конечно же, это очень удобно.
Например, поменяем элементы местами:
<div>Первый</div>
<div>Второй</div>
<script>
var first = document.body.children[0];
var last = document.body.children[1];
// нет необходимости в предварительном removeChild(last)
document.body.insertBefore(last, first); // поменять местами
</script>
В качестве реального примера рассмотрим добавление сообщения на страницу. Чтобы показывалось посередине экрана и было красивее, чем обычный alert.
HTML-код для сообщения (без JS):
<style>
.message {
width: 300px;
height: 130px;
border: 1px solid gray;
text-align: center;
}
.message h1 {
color: red;
background: azure;
font-size: 16px;
height: 30px;
line-height: 30px;
margin: 0;
}
.message .content {
height: 50px;
padding: 10px;
}
</style>
<div class="message">
<h1>Заголовок</h1>
<div class="content">Текст Сообщения</div>
<input class="ok" type="button" value="OK"/>
</div>

Как видно - сообщение вложено в div фиксированного размера message и состоит из заголовка h1, тела content и кнопки OK, которая нужна, чтобы сообщение закрыть.
Кроме того, добавлено немного стилей, чтобы как-то смотрелось.
Для создания сложных структур DOM, как правило, используют либо готовый «шаблонный узел» и метод cloneNode, либо свойство innerHTML.
Следующая функция создает сообщение с указанным телом и заголовком.
function createMessage(title, body) {
// (1)
var container = document.createElement('div');
// (2)
container.innerHTML = '<div class="message"> \
<h1>' + title + '</h1> \
<div class="content">' + body + '</div> \
<input class="ok" type="button" value="OK"> \
</div>';
// (3)
return container.firstChild;
}
Как видно, она поступает довольно хитро. Чтобы создать элемент по текстовому шаблону, она сначала создает временный элемент container (1), а потом записывает (2) сообщение как innerHTML временного элемента. Теперь готовый элемент можно получить как container.firstChild и вернуть в (3).
Полученный элемент можно добавить в DOM:
var messageElem = createMessage('Привет, Мир!', 'Я - элемент DOM!')
document.body.appendChild(messageElem);
Окончательный результат:
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<link type="text/css" rel="stylesheet" href="alert.css" />
</head>
<body>
<script>
function createMessage(title, body) {
var container = document.createElement('div');
container.innerHTML = '<div class="message"> \
<h1>' + title + '</h1> \
<div class="content">' + body + '</div> \
<input class="ok" type="button" value="OK"> \
</div>';
return container.firstChild;
}
var messageElem = createMessage('Привет, Мир!', 'Я - элемент DOM!')
document.body.appendChild(messageElem);
</script>
</body>
</html>

Как правило, при создании узлов и заполнении их используется innerHTML. Но текстовые узлы тоже имеют интересную область применения.
У них есть две особенности.
Допустим, у нас есть пустой узел DOM elem.
Одинаковый ли результат дадут эти скрипты?
Первый:
elem.appendChild(document.createTextNode(text));
Второй:
elem.innerHTML = text;
createTextNode создает текст '<b>текст</b>':<div></div>
<script>
var text = '<b>текст</b>';
var elem = document.body.children[0];
elem.appendChild(document.createTextNode(text));
</script>
innerHTML присваивает HTML <b>текст</b>:<div></div>
<script>
var text = '<b>текст</b>';
var elem = document.body.children[0];
elem.innerHTML = text;
</script>
Итак, отличий два:
createTextNode('<b>...</b>') любые специальные символы и теги в строке будут интерпретированы как текст. А innerHTML вставит их как HTML.Методы для создания узлов:
document.createElement(tag) — создает элемент;document.createTextNode(value) — создает текстовый узел;elem.cloneNode(deep) — клонирует элемент, если deep == true, то со всеми потомками.Вставка и удаление узлов:
parent.appendChild(elem);parent.insertBefore(elem, nextSibling);parent.removeChild(elem);parent.replaceChild(elem, currentElem).Все эти методы возвращают elem.
Запомнить порядок аргументов очень просто: новый(вставляемый) элемент — всегда первый.
Методы для изменения DOM также описаны в спецификации DOM Level 1.