var arrayish = {0: "один", 1: "два", length: 2};
var real = Array.prototype.slice.call(arrayish, 0);
real.forEach(function(elt) { console.log(elt); });
// → один
// два
Для создания узлов-элементов (тип 1) можно использовать document.createElement
. Метод принимает имя тега и возвращает новый пустой узел заданного типа. Следующий пример определяет инструмент elt
, создающий узел-элемент и использующий остальные аргументы в качестве его детей. Эта функция потом используется для добавления дополнительной информации к цитате.
<blockquote id="quote">
Никакая книга не может быть закончена. Во время работы над ней мы узнаём достаточно для того, чтобы найти её незрелой сразу же после того, как мы отвлеклись от неё.
</blockquote>
<script>
function elt(type) {
var node = document.createElement(type);
for (var i = 1; i < arguments.length; i++) {
var child = arguments[i];
if (typeof child == "string")
child = document.createTextNode(child);
node.appendChild(child);
}
return node;
}
document.getElementById("quote").appendChild(
elt("footer", "—",
elt("strong", "Карл Поппер"),
", предисловие ко второму изданию ",
elt("em", "Открытое общество и его враги "),
", 1950"));
</script>
Атрибуты
К некоторым элементам атрибутов, типа href
у ссылок, можно получить доступ через одноимённое свойство объекта. Это возможно для ограниченного числа часто используемых стандартных атрибутов.
Но HTML позволяет назначать узлам любые атрибуты. Это полезно, т. к. позволяет вам хранить дополнительную информацию в документе. Если вы придумаете свои названия атрибутов, их не будет среди свойств узла-элемента. Вместо этого вам надо будет использовать методы getAttribute
и setAttribute
для работы с ними.
<p data-classified="secret">Код запуска 00000000.</p>
<p data-classified="unclassified">У кошки четыре ноги.</p>
<script>
var paras = document.body.getElementsByTagName("p");
Array.prototype.forEach.call(paras, function(para) {
if (para.getAttribute("data-classified") == "secret")
para.parentNode.removeChild(para);
});
</script>
Рекомендую перед именами придуманных атрибутов ставить data-
, чтобы быть уверенным, что они не конфликтуют с любыми другими. В качестве простого примера мы напишем подсветку синтаксиса, который ищет теги <pre>
(“preformatted”, предварительно отформатированный – используется для кода и простого текста) с атрибутом data-language
(язык) и довольно грубо пытается подсветить ключевые слова в языке.
function highlightCode(node, keywords) {
var text = node.textContent;
node.textContent = ""; // Очистим узел
var match, pos = 0;
while (match = keywords.exec(text)) {
var before = text.slice(pos, match.index);
node.appendChild(document.createTextNode(before));
var strong = document.createElement("strong");
strong.appendChild(document.createTextNode(match[0]));
node.appendChild(strong);
pos = keywords.lastIndex;
}
var after = text.slice(pos);
node.appendChild(document.createTextNode(after));
}
Функция highlightCode
принимает узел <pre>
и регулярку (с включённой настройкой global), совпадающую с ключевым словом языка программирования, которое содержит элемент.
Свойство textContent
используется для получения всего текста узла, а затем устанавливается в пустую строку, что приводит к очищению узла. Мы в цикле проходим по всем вхождениям выражения keyword, добавляем между ними текст в виде простых текстовых узлов, а совпавший текст (ключевые слова) добавляем, заключая их в элементы <strong>
(жирный шрифт).
Мы можем автоматически подсветить весь код страницы, перебирая в цикле все элементы <pre>
, у которых есть атрибут data-language
, и вызывая на каждом highlightCodeс
правильной регуляркой.
var languages = {
javascript: /\b(function|return|var)\b/g /* … etc */
};
function highlightAllCode() {
var pres = document.body.getElementsByTagName("pre");
for (var i = 0; i < pres.length; i++) {
var pre = pres[i];
var lang = pre.getAttribute("data-language");
if (languages.hasOwnProperty(lang))
highlightCode(pre, languages[lang]);
}
}
Вот пример: