Категории
Самые читаемые
onlinekniga.com » Компьютеры и Интернет » Программирование » Выразительный JavaScript - Марейн Хавербеке

Выразительный JavaScript - Марейн Хавербеке

Читать онлайн Выразительный JavaScript - Марейн Хавербеке

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 40 41 42 43 44 45 46 47 48 ... 79
Перейти на страницу:

<p>Один</p>

<p>Два</p>

<p>Три</p>

<script>

  var paragraphs = document.body.getElementsByTagName("p");

  document.body.insertBefore(paragraphs[2], paragraphs[0]);

</script>

Узел может существовать в документе только в одном месте. Поэтому вставляя параграф «Три» перед параграфом «Один» мы фактически удаляем его из конца списка и вставляем в начало, и получаем «Три/Один/Два». Все операции по вставке узла приведут к его исчезновению с текущей позиции (если у него таковая была).

Метод replaceChild используется для замены одного дочернего узла другим. Он принимает два узла: новый, и тот, который надо заменить. Заменяемый узел должен быть дочерним узлом того элемента, чей метод мы вызываем. Как replaceChild, так и insertBefore в качестве первого аргумента ожидают получить новый узел.

Создание узлов

В следующем примере нам надо сделать скрипт, заменяющий все картинки (тег <img>) в документе текстом, содержащимся в их атрибуте alt, который задаёт альтернативное текстовое представление картинки.

Для этого надо не только удалить картинки, но и добавить новые текстовые узлы им на замену. Для этого мы используем метод document.createTextNode.

<p>Это <img src="img/cat.png" alt="Кошка"> в

  <img src="img/hat.png" alt="сапожках">.</p>

<p><button onclick="replaceImages()">Заменить</button></p>

<script>

  function replaceImages() {

    var images = document.body.getElementsByTagName("img");

    for (var i = images.length - 1; i >= 0; i--) {

      var image = images[i];

      if (image.alt) {

        var text = document.createTextNode(image.alt);

        image.parentNode.replaceChild(text, image);

      }

    }

  }

</script>

Получая строку, createTextNode даёт нам тип 3 узла DOM (текстовый), который мы можем вставить в документ, чтобы он был показан на экране.

Цикл по картинкам начинается в конце списка узлов. Это сделано потому, что список узлов, возвращаемый методом getElementsByTagName (или свойством childNodes) постоянно обновляется при изменениях документа. Если б мы начали с начала, удаление первой картинки привело бы к потере списком первого элемента, и во время второго прохода цикла, когда i равно 1, он бы остановился, потому что длина списка стала бы также равняться 1.

Если вам нужно работать с фиксированным списком узлов вместо «живого», можно преобразовать его в настоящий массив при помощи метода slice.

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]);

  }

}

Вот пример:

<source lang="html">

<p>А вот и она, функция идентификации:</p>

<pre data-language="javascript">

function id(x) { return x; }

Есть один часто используемый атрибут, class, имя которого является ключевым словом в JavaScript. По историческим причинам, когда старые реализации JavaScript не умели обращаться с именами свойств, совпадавшими с ключевыми словами, этот атрибут доступен через свойство под названием className. Вы также можете получить к нему доступ по его настоящему имени class через методы getAttribute и setAttribute.

Расположение элементов (layout)

Вы могли заметить, что разные типы элементов располагаются по-разному. Некоторые, типа параграфов <p> и заголовков <h1> растягиваются на всю ширину документа и появляются на отдельных строках. Такие элементы называют блочными. Другие, как ссылки <a> или жирный текст <strong> появляются на одной строчке с окружающим их текстом. Они называются встроенными (inline).

Для любого документа браузеры могут построить расположение элементов, расклад, в котором у каждого будет размер и положение на основе его типа и содержимого. Затем этот расклад используется для создания внешнего вида документа.

Размер и положение элемента можно узнать через JavaScript. Свойства offsetWidth и offsetHeight выдают размер в пикселях, занимаемый элементом. Пиксель – основная единица измерений в браузерах, и обычно соответствует размеру минимальной точки экрана. Сходным образом, clientWidth и clientHeight дают размер внутренней части элемента, не включая ширину его границ (border).

<p style="border: 3px solid red">

  Я в коробочке

</p>

<script>

1 ... 40 41 42 43 44 45 46 47 48 ... 79
Перейти на страницу:
На этой странице вы можете бесплатно читать книгу Выразительный JavaScript - Марейн Хавербеке.
Комментарии