Как и во внешних файлах HTML, организация разметки отделена от ее стиля, формата и поведения. Конечно, вы можете изменить стиль элементов или текста с помощью JavaScript, но гораздо интереснее фактически изменить организацию расположения вашей разметки.
Просто помните, что ваша разметка обеспечивает лишь организацию, структуру, и вы будете на пути к успеху. Сделайте небольшой шаг дальше, и вы увидите, как браузер берет всю эту текстовую организацию и превращает ее во что-то очень интересное, набор объектов, каждый из которых можно изменить, добавить или удалить.
Преимущества текстовой разметки
Прежде чем обсуждать веб-браузеры, стоит задуматься, почему простой текст является лучшим выбором для хранения HTML (дополнительную информацию см. в некоторых других идеях о разметке). Независимо от плюсов и минусов, достаточно вспомнить, что HTML отправляется по сети в веб-браузер каждый раз при просмотре страницы (для краткости не учитываются кэши и т.п.). На самом деле не существует более эффективного способа доставки текста. Двоичные объекты, графические представления страниц, реорганизованные блоки разметки и т. д. — все это труднее передавать по сети, чем обычные текстовые файлы.
Кроме того, браузер еще и добавляет славы. Современные браузеры позволяют пользователям изменять размер текста, масштабировать изображения, загружать CSS или JavaScript страницы (в большинстве случаев) и многое другое, что полностью исключает отправку любого графического представления страницы в браузер. Однако браузеру нужен необработанный HTML-код, чтобы он мог применять любую обработку к странице в браузере, вместо того, чтобы доверять браузеру выполнение этой задачи. Аналогичным образом, для отделения CSS от JavaScript и CSS от разметки HTML требуется формат, который можно легко разделить. Еще раз, текстовые файлы — лучший метод для этой задачи.
И последнее, но не менее важное: помните, что новые стандарты (такие как HTML 4.01 и XHTML 1.0 и 1.1) обещают отделить контент (данные на странице) от представления и стиля (обычно применяемого CSS). Если бы программистам пришлось отделить HTML от CSS, а затем заставить браузер получать некоторое представление страницы, которое объединяет различные части страницы, они потеряли бы большую часть преимуществ этих стандартов. Разделение этих частей при их поступлении в браузер дает браузеру беспрецедентную гибкость при получении HTML с сервера.
Дополнительные мысли о
редактировании разметки обычного текста: правильно или неправильно?
Обычный текст идеально подходит для хранения разметки, но не подходит для ее редактирования. Популярным является использование IDE, таких как Macromedia DreamWeaver или более мощной Microsoft® FrontPage®, для управления разметкой веб-страниц. Эти среды часто предоставляют ярлыки и помощь для создания веб-страниц, особенно при использовании CSS и JavaScript, которые берутся из файлов, отличных от фактической разметки страницы. Неважно, что многие по-прежнему предпочитают старый добрый Блокнот или vi (признаюсь, я один из них). В любом случае конечным результатом является текстовый файл, полный разметки.
Текст в Интернете.
Было сказано много хорошего: текст — лучший носитель для документов, таких как HTML или CSS, которые тысячи раз передаются через Интернет. Когда я говорю, что браузеру сложно представлять текст, я конкретно имею в виду преобразование текста в визуальную графическую страницу для просмотра пользователем. Это не имеет ничего общего с тем, как браузер на самом деле получает страницу из веб-браузера, и в этом случае текст по-прежнему является лучшим выбором;
Недостатки текстовой разметки
Так же, как текстовая разметка имеет неожиданные преимущества для дизайнеров и создателей страниц, она также имеет и весьма неожиданные недостатки для браузеров. В частности, браузерам сложно напрямую визуально представлять текстовую разметку пользователю (подробности см. в некоторых других идеях о разметке). Рассмотрим следующие распространенные задачи браузера:
· Применение стилей CSS (обычно из нескольких таблиц стилей во внешних файлах) к разметке на основе типа элемента, класса, идентификатора и его положения в HTML-документе.
· Применяйте стили и форматирование к различным частям HTML-документа на основе кода JavaScript (обычно расположенного во внешнем файле).
·Изменить значения полей формы на основе кода JavaScript.
·На основе кода JavaScript поддерживает визуальные эффекты, такие как переворачивание и замена изображений.
Сложность заключается не в кодировании этих задач; в них все довольно просто. Сложность возникает из-за того, что браузер фактически выполняет запрошенное действие. Если разметка хранится в виде текста, например, если вы хотите ввести текст (text-align:center) в элемент p класса center-text, как этого добиться?
·Добавить встроенные стили в текст?
· Применять стили к HTML-тексту в браузере и сохранять содержимое по центру или нет?
·Применить нестилизованный HTML, а затем применить форматирование?
Именно из-за этих очень сложных проблем сегодня так мало людей пишут браузеры. (Тот, кто написал браузер, должен принять мою искреннюю благодарность.)
Нет никаких сомнений в том, что простой текст не является хорошим способом хранения HTML-кода браузера, хотя текст является лучшим решением для получения разметки страницы. Добавьте сюда возможность JavaScript изменять структуру страницы, и все станет немного более тонким. Должен ли браузер перезаписать измененную структуру на диск? Как сохранить последнюю версию документа?
Конечно, текст не является ответом. Его трудно модифицировать, трудно применить к нему стили и поведение, и он принципиально далек от динамической природы современных веб-страниц.
Ответом на проблемуиспользования древовидных представлений
(по крайней мере, ответ, выбранный сегодняшними веб-браузерами) является использование древовидной структуры для представления HTML. См. листинг 1, довольно простую и скучную HTML-страницу, представляющую разметку для этой статьи.
Листинг 1. Простая HTML-страница<html>
в текстовой разметке
<голова>
<title>Деревья, деревья повсюду</title>
</голова>
<тело>
<h1>Деревья, деревья повсюду</h1>
<p>Добро пожаловать на <em>действительно</em> скучную страницу.</p>
<дел>
Приходите скоро снова.
<img src="come-again.gif" />
</div>
</тело>
</html>
Браузер принимает страницу и преобразует ее в древовидную структуру, как показано на рисунке 1.
Чтобы сохранить актуальность этой статьи, я немного ее упростил. Эксперты в DOM или XML знают о влиянии пробелов на способ представления и разбивки текста документа в древовидной структуре веб-браузера. Поверхностное понимание только делает вещи двусмысленными, поэтому, если вы хотите выяснить влияние пробелов, это лучший вариант, если нет, просто продолжайте читать и не думайте об этом; Когда это станет проблемой, тогда вы узнаете все, что вам нужно.
Помимо фактического фона дерева, первое, что вы можете заметить, это то, что все в дереве начинается с самого внешнего элемента, содержащего HTML, элемента html. Используя метафору дерева, это называется корневым элементом. Поэтому, хотя это нижний уровень дерева, когда вы смотрите на дерево и анализируете его, я обычно начинаю с него. Если это сработает, вы могли бы перевернуть все дерево вверх дном, но это немного растянет метафору дерева.
Линии, идущие от корня, представляют отношения между различными помеченными частями. Элементы head и body являются дочерними элементами корневого элемента html; заголовок является дочерним элементом заголовка, а текст «Деревья, деревья повсюду» — дочерним элементом заголовка. Таким образом организуется все дерево до тех пор, пока браузер не приобретет структуру, аналогичную рисунку 1.
Некоторая дополнительная терминология.
Чтобы сохранить метафору дерева, голова и тело называются ветвями HTML. Их называют ветвями, потому что у них есть свои дети. Когда вы дойдете до конца дерева, вы перейдете к основному тексту, например «Деревья, деревья повсюду» и «действительно» их часто называют листьями, потому что у них нет собственных детей. Вам не нужно запоминать все эти термины, гораздо проще просто представить древовидную структуру, когда вы пытаетесь понять, что означает тот или иной термин.
Значения объекта
Теперь, когда вы поняли некоторую базовую терминологию, пришло время сосредоточиться на небольшом прямоугольнике, содержащем имя и текст элемента (рис. 1). Каждый прямоугольник является объектом; браузер решает некоторые проблемы с текстом внутри него. Используя объекты для представления каждой части HTML-документа, вы можете легко изменить организацию, применить стили, разрешить JavaScript доступ к документу и многое другое.
Типы объектов и
маркеры свойств. Каждый возможный тип имеет свой собственный тип объекта. Например, элементы в HTML представлены типом объекта Element. Текст в документе представлен типом «Текст», атрибуты — типом «Атрибут» и т. д.
Таким образом, веб-браузеры могут не только использовать объектную модель для представления документов (таким образом избегая необходимости иметь дело со статическим текстом), но они также могут использовать типы объектов, чтобы сразу определить, что это такое. HTML-документ анализируется и преобразуется в коллекцию объектов, как показано на рисунке 1, и такие вещи, как угловые скобки и escape-последовательности (например, используйте < для < и > для >), больше не являются проблемой. Это значительно упрощает работу браузера (по крайней мере, после анализа входного HTML). Легко определить, является ли что-то элементом или атрибутом, и определить, как обращаться с объектами этого типа.
Используя объекты, веб-браузер может изменять свойства этих объектов. Например, каждый объект-элемент имеет родительский элемент и список дочерних элементов. Таким образом, добавление нового дочернего элемента или текста просто добавляет новый дочерний элемент в список дочерних элементов элемента. У этих объектов также есть свойство style, поэтому быстро изменить стиль элемента или сегмента текста очень просто. Например, чтобы использовать JavaScript для изменения высоты элемента div, это выглядит так:
someDiv.style.height = "300px"
Другими словами, веб-браузер позволяет очень легко изменить внешний вид и структуру дерева с помощью объекта
;характеристики. Сравните это со сложными действиями, которые браузеру приходится делать внутри себя, чтобы представить страницу в виде текста: каждое изменение свойства или структуры требует от браузера перезаписи статического файла, его повторного анализа и повторного отображения на экране. С объектами все это решается.
Теперь найдите время, чтобы развернуть некоторые HTML-документы и обрисовать их в виде дерева. Хотя это может показаться необычным запросом (особенно в такой статье, содержащей так мало кода), если вы надеетесь манипулировать этими деревьями, вам необходимо знать их структуру.
По пути вы можете обнаружить некоторые странные вещи. Например, рассмотрим следующее:
Что происходит с атрибутом?
· А как насчет текста, разбитого на элементы (например, em и b)?
· А как насчет HTML, который не структурирован должным образом (например, когда отсутствует закрывающий тег p)?
Ознакомившись с этими вопросами, вы сможете лучше понять следующие разделы.
Строгость иногда полезна.
Если вы попробуете упражнение, которое я только что упомянул, вы можете обнаружить некоторые потенциальные проблемы с отмеченным древовидным представлением (если нет, просто поверьте мне на слово!). Фактически, в листинге 1 и на рисунке 1 можно обнаружить некоторые проблемы. Сначала посмотрим, как разлагается элемент p. Если вы спросите среднестатистического веб-разработчика: «Каково текстовое содержимое элемента p?», наиболее распространенным ответом будет: «Добро пожаловать на действительно скучную веб-страницу». Если вы сравните это с рисунком 1, вы увидите, что этот ответ (хотя и логичный) просто неверен.
Фактически, элемент p имеет три разных дочерних объекта, ни один из которых не содержит полного текста «Добро пожаловать на очень скучную веб-страницу». Вы найдете части текста, такие как «Добро пожаловать на» и «скучная веб-страница», но не весь текст. Чтобы понять это, помните, что все в разметке должно быть преобразовано в объект определенного типа.
Кроме того, порядок не имеет значения! Можете ли вы представить, как пользователь отреагировал бы на действия веб-браузера, если бы браузер отображал правильные объекты, но в другом порядке, чем вы указали их в HTML? Что, если абзац зажат между заголовком страницы и заголовком статьи, а вы сами организуете свой документ не так? Очевидно, что браузер должен поддерживать порядок элементов и текста.
В этом примере элемент p состоит из трех разных частей:
· Текст перед элементом em · Сам элемент em · Текст после элемента em
Если вы напутаете в этом порядке, вы можете сосредоточиться на неправильной части текста. Чтобы все было в порядке, элемент p имеет три дочерних объекта в порядке, показанном в HTML-коде листинга 1. Более того, ключевой текст «на самом деле» не является дочерним элементом p; это дочерний элемент em, дочерний элемент p;
Очень важно понять эту концепцию. Хотя текст «действительно» скорее всего появится вместе с другим текстом элемента p, он по-прежнему является прямым дочерним элементом элемента em. Он может иметь формат, отличный от другого текста p, и его можно перемещать независимо от другого текста.
Чтобы иметь это в виду, попробуйте составить диаграмму HTML в листингах 2 и 3, чтобы убедиться, что текст имеет правильный родительский элемент (независимо от того, как текст в конечном итоге будет отображаться на экране).
Листинг 2. Разметка
<html>
с умной вложенностью элементов
<голова>
<title>Это немного сложно</title>
</голова>
<тело>
<h1>Обратите <u>пристальное</u> внимание, хорошо?</h1>
<дел>
<p>Этот p на самом деле не <em>необходим</em>, но он делает
<span id="bold-text">структура <i>и</i> организации</span>
страницы, за которой легче следить.</p>
</div>
</тело>
</html>
Листинг 3. Более умное вложение элементов
<html>
<голова>
<title>Вложение еще сложнее</title>
</голова>
<тело>
<div id="main-body">
<div id="содержание">
<таблица>
<tr><th>Шаги</th><th>Процесс</th></tr>
<tr><td>1</td><td>Определите <em>корневой элемент</em>.</td></tr>
<tr><td>2</td><td>Сначала разберитесь с <span id="code">головой</span>,
как обычно это легко.</td></tr>
<tr><td>3</td><td>Проработайте <span id="code">тело</span>.
Просто <em>не торопитесь</em>.</td></tr>
</таблица>
</div>
<div id="закрытие">
Эта ссылка <em>не</em> активна, но если бы она была активна, ответы
к этому <a href="answers.html"><img src="exercision.gif" /></a> будет
будь там, но <em>все равно сделай упражнение!</em>
</div>
</div>
</тело>
</html>
Ответы на эти упражнения вы найдете в файлах GIF в конце этой статьи: Tricky-solution.gif на рис. 2 и Trickier-solution.gif на рис. 3. Не подглядывайте, сначала найдите время, чтобы ответить автоматически. Это поможет вам понять, насколько строгие правила применяются при организации дерева, и действительно поможет вам освоить HTML и его древовидную структуру.
А что насчет атрибутов?
Сталкиваетесь ли вы с некоторыми проблемами, пытаясь понять, что делать со свойствами? Как упоминалось ранее, атрибут имеет свой собственный тип объекта, но атрибут действительно не является дочерним элементом отображающего его элемента. Как вы заметите, вложенный элемент и текст не находятся на одном и том же «уровне» атрибута. ответы на упражнения в листингах 2 и 3. Свойства не показаны.
Свойства фактически хранятся в объектной модели, используемой браузерами, но у них есть некоторые особые случаи. Каждый элемент имеет список доступных свойств, отдельный от списка дочерних объектов. Таким образом, элемент div может иметь список, содержащий атрибут «id» и другой атрибут «class».
Помните, что атрибуты элемента должны иметь уникальные имена, то есть элемент не может иметь два атрибута «id» или два атрибута «class». Это упрощает обслуживание и доступ к списку. Как вы увидите в следующей статье, вы можете просто вызвать такой метод, как getAttribute("id"), чтобы получить значение атрибута по имени. Подобные вызовы методов также можно использовать для добавления свойств или установки (сброса) значений существующих свойств.
Стоит отметить, что уникальность имен атрибутов отличает этот список от списка подобъектов. Элемент p может иметь несколько элементов em, поэтому список дочерних объектов может содержать несколько дубликатов. Хотя дочерние списки и списки свойств работают одинаково, один из них может содержать дубликаты (дочерние элементы объекта), а другой — нет (свойства объекта-элемента). Наконец, атрибуты есть только у элементов, поэтому у текстовых объектов нет дополнительного списка для хранения атрибутов.
Беспорядочный HTML
Прежде чем перейти к тому, как браузеры преобразуют разметку в древовидное представление, стоит изучить еще одну тему, а именно, как браузеры обрабатывают неправильно сформированную разметку. «Хорошо сформированный» — это термин, широко используемый в XML и имеющий два основных значения:
· Каждому открывающему тегу соответствует соответствующий закрывающий тег. Таким образом, каждый <p> в документе соответствует </p>, каждый <div> соответствует </div> и так далее.
Самый внутренний начальный тег соответствует самому внутреннему конечному тегу, затем следующий самый внутренний начальный тег соответствует следующему самому внутреннему конечному тегу и так далее. Таким образом, <b><i>жирный шрифт и курсив</b></i> недопустимы, поскольку самый внутренний открывающий тег <i> не соответствует самому внутреннему закрывающему тегу <b> должным образом. Чтобы сделать его правильно сформированным, поменяйте порядок открывающих или закрывающих тегов. (Если вы переключите оба, проблема все равно возникнет).
Обратите внимание на эти два правила. Эти два правила не только упрощают организацию документов, но и устраняют неопределенность. Следует ли сначала применять жирный шрифт, а затем курсив? Или как раз наоборот? Если этот порядок и неопределенность не кажутся вам такими уж важными, имейте в виду, что CSS позволяет правилам переопределять другие правила, поэтому, например, если текст в элементе b имеет шрифт, отличный от шрифта в элементе i, порядок применения форматирования изменится. Это очень важно. Поэтому правильность HTML играет решающую роль.
Если браузер получает документ неправильного формата, он сделает все возможное. Полученная древовидная структура будет в лучшем случае приближением к исходной странице, которую задумал автор, а в худшем случае будет неузнаваемой. Если вы когда-нибудь загружали страницу в браузер и видели совершенно неожиданные результаты, вы, вероятно, смотрели на результаты браузера и догадывались, какой должна быть ваша структура, и продолжали работать в разочаровании. Конечно, решить эту проблему довольно просто: убедитесь, что документ правильно отформатирован! Если вы не знаете, как писать стандартизированный HTML, обратитесь за помощью к своим ресурсам.
Введение в DOM
Теперь вы знаете, что браузеры преобразуют веб-страницы в представления объектов, и, возможно, вы даже догадались, что представления объектов представляют собой деревья DOM. DOM означает объектную модель документа и представляет собой спецификацию, доступную от Консорциума World Wide Web (W3C) (вы можете увидеть некоторые ссылки, связанные с DOM, в разделе «Ресурсы»).
Но что еще более важно, DOM определяет типы и свойства объектов, позволяя браузеру представлять разметку. (Следующая статья этой серии будет посвящена спецификациям использования DOM в коде JavaScript и Ajax.)
Объект документа
Сначала вам необходимо получить доступ к самой объектной модели. Использовать встроенную переменную документа в любом коде JavaScript, который выполняется на веб-странице, можно написать так:
var domTree = document;
Конечно, этот код сам по себе бесполезен, но он демонстрирует, что каждый веб-сайт
;браузер создает документы. Объекты можно использовать в коде JavaScript, а также демонстрируется полное дерево разметки представления объектов (рис. 1).
Каждый элемент является узлом
. Очевидно, что объект документа важен, но это только начало. Прежде чем идти дальше, нужно выучить еще один термин: узлы. Вы уже знаете, что каждая часть разметки представлена объектом, но это не просто объект, а объект определенного типа — узел DOM. Более конкретные типы, такие как текст, элементы и атрибуты, наследуются от этого базового типа узла. Таким образом, могут быть текстовые узлы, узлы элементов и узлы атрибутов.
Если у вас уже есть большой опыт программирования на JavaScript, вы, вероятно, уже работаете с кодом DOM. Если вы до сих пор следили за этой серией статей об Ajax, вы, должно быть, уже некоторое время работали с кодом DOM. Например, строка кода var Number = document.getElementById("phone").value; использует DOM для поиска определенного элемента, а затем извлекает значение этого элемента (в данном случае — поле формы). Таким образом, даже если вы этого не осознаете, вы используете DOM каждый раз, когда вводите документ в код JavaScript.
Чтобы уточнить термины, которые вы уже изучили, дерево DOM — это дерево объектов, а точнее, дерево узловых объектов. В приложениях Ajax или любом другом JavaScript вы можете использовать эти узлы для создания таких эффектов, как удаление элементов и их содержимого, выделение определенного текста или добавление новых элементов изображения. Поскольку все они происходят на стороне клиента (код, выполняемый в веб-браузере), эти эффекты происходят немедленно, без связи с сервером. Конечным результатом часто является то, что приложение становится более отзывчивым, поскольку содержимое веб-страницы меняется без долгих пауз, пока запрос направляется на сервер и интерпретируется ответ.
В большинстве языков программирования вам необходимо узнать фактическое имя объекта каждого типа узла, изучить доступные свойства и выяснить типы и приведения, но в JavaScript в этом нет необходимости; Вы можете просто создать переменную и присвоить ей желаемый объект (как вы уже видели):
var domTree = document;
вар phoneNumberElement = document.getElementById("телефон");
var phoneNumber = phoneNumberElement.value
Типа нет, JavaScript создает переменную по мере необходимости и присваивает ей правильный тип. В результате работа с DOM из JavaScript становится тривиальной (будущая статья будет посвящена DOM применительно к XML, что будет еще более изобретательно).
Взаключение
я хочу оставить вас в некотором напряжении. Очевидно, что это не полностью исчерпывающее описание DOM; на самом деле эта статья представляет собой лишь введение в DOM; DOM — это гораздо больше, чем то, что я представил сегодня!
В следующей статье этой серии мы подробно рассмотрим эти идеи и углубимся в то, как использовать DOM в JavaScript для обновления веб-страниц, быстрого изменения HTML и создания более интерактивного опыта для ваших пользователей. Я снова вернусь к DOM в следующей статье, посвященной использованию XML в запросах Ajax. Итак, будьте знакомы с DOM, который является основной частью приложений Ajax.
На этом этапе глубокое понимание DOM будет довольно простым, например, подробное описание того, как перемещаться по дереву DOM, получать значения элементов и текста, перебирать списки узлов и т. д., но это может оставить вас с Создается впечатление, что DOM — это код, но это не так.
Прежде чем читать следующую статью, попробуйте подумать о древовидной структуре и опробуйте ее на собственном HTML-коде, чтобы увидеть, как веб-браузер преобразует HTML в древовидное представление разметки. Кроме того, подумайте об организации дерева DOM и попрактикуйтесь в ней с особыми случаями, представленными в этой статье: атрибуты, текст со смешанными элементами и элементы без текстового содержимого (например, элемент img).
Твердое понимание этих концепций, а затем изучение синтаксиса JavaScript и DOM (следующая статья) значительно облегчит реагирование.
И не забывайте, что к листингам 2 и 3 есть ответы вместе с примером кода!