Однако сценарии для DOM значительно более мощный инструмент, чем просто средство для изменения свойств CSS существующего HTML. Можно также динамически создавать новый код HTML, который никогда не присутствовал на странице с самого начала. Например, на сайте новостей технологии Slashdot, ссылка в комментариях выводит место назначения ссылки в квадратных скобках, поэтому ссылка вида <a href="http://opera.com"> A web browser </a> будет выводиться как <a href="http://opera.com">A web browser</a> [opera.com]. (Это было сделано, чтобы исключить использование фальшивых ссылок, направляющих пользователя в нежелательное место.) Добавление этого небольшого кода HTML, выводящего домен места назначения каждой ссылки на странице, легко делается с помощью JavaScript.
Создание новых элементов HTML делается с помощью функции document.createElement. Для этого примера нужно добавить только одну вещь: после каждой ссылки мы добавляем span, содержащий текст, указывающий домен ссылки (посмотрите страницу linkify.html (http://dev.opera.com/articles/view/creating-and-modifying-html/linkify.html) содержащую действующий пример). Код HTML примера выглядит следующим образом:
<p id="start">This is some text that has
<a href="http://www.w3.org/TR/html4/struct/links.html">links</a> in it
to various places, including <a href="http://www.opera.com">Opera</a>,
<a href="http://www.bbc.co.uk/">the BBC</a> and an internal link to
<a href="#start">the beginning of this section</a>. All the external links
Сначала он находит все ссылки (getElementsByTagName("a")) в документе
var matches = links[i].href.match(/^http:\/\/(.*?)\//);
if (matches) {
...
}
Эта строка использует регулярное выражение на каждой ссылке, чтобы определить, что место назначение начинается с http://что-то/. Если это так …
var linkdomain = matches[1];
var span = document.createElement("span");
var spantext = document.createTextNode(" ["+linkdomain+"]");
span.appendChild(spantext);
… следующая часть сначала получает "домен ссылки", часть www.opera.com ссылки. Затем с помощью document.createElement создается элемент <span>. Затем создается "textNode" ("текстовыйУзел"). В то время как сами элементы HTML создаются с помощью document.createElement, весь текст в документе HTML фактически содержится в "textNode", и их необходимо создать отдельно. Нет необходимости беспокоиться об этом (или даже знать об этом) при написании реального HTML, но нужно знать об этом при создании элементов с помощью сценария DOM. Текст в textNode является фактически " [домен]", созданный конкатенацией (соединением вместе) строк. Наконец, эта часть использует метод appendChild элемента <span>, чтобы поместить textNode внутрь span.
Эта строка добавляет span в документ. В этом месте span является ссылкой на элемент HTML, который выглядит следующим образом:
<span> [example.com]</span>
Этот элемент, однако, не является частью документа. Он не является пока частью никакого документа, он просто находится в некоторой неопределенности. Добавление элемента в документ можно сделать одним из двух способов: используя appendChild как выше, или используя insertBefore. Функция appendChild добавляет наш элемент в конце существующего элемента (именно поэтому она называет append). Так как мы хотим добавить ее в середине существующего элемента, нам нужно использовать insertBefore. Вспомните, что наш текущий фрагмент кода HTML выглядит примерно следующим образом:
<p>... text that has
<a href="http://www.w3.org/TR/html4/struct/links.html">links</a> in it
to ...
Это приводит к дереву DOM, показанному на рисунке 9.1:
Рис. 9.1. Дерево DOM tree перед добавлением элемента span после ссылки
Мы хотим вставить новый span между <a> и textNode "in it to", чтобы он появлялся после <a>. Это приведет к дереву DOM как на рисунке 9.2.
увеличить изображение Рис. 9.2. Дерево DOM после добавления элемента span
Здесь было бы удобно иметь возможность сказать: "вставьте новый span после ссылки". К сожалению функции insertAfter нет. Вместо этого мы должны вставлять его перед элементом после ссылки (несколько запутано, но подумайте об этом, и все встанет на место). Краткая запись для выражения "вещь после элемента помеченного el" будет el.nextSibling. Функция insertBefore должна вызываться на элементе, в который происходит вставка, т.е. на предке <p> ссылки, легко доступной с помощью link.parentNode. Поэтому весь вызов, как выше, будет
То есть, находим предка (<p>) ссылки, которая обрабатывается (links[i]) в данный момент, и вставляем созданный элемент span перед элементом после ссылки (links[i].nextSibling). Использование HTML в виде дерева DOM таким образом и вставка новых элементов в него, может вначале вызывать непонимание, но скоро все становится понятным при достаточной практике.