--- title: Динамически изменяемый пользовательский интерфейс на XUL slug: Динамически_изменяемый_пользовательский_интерфейс_на_XUL tags: - DOM - Extensions - XUL ---
В этой статье обсуждается управление XUL интерфейсами с использованием DOM и других API. Здесь объясняется принцип документов DOM, приводится несколько простых примеров использования вызовов DOM для выполнения простейших манипуляций с документом, после чего приводится пример, демонстрирующий работу с анонимным XBL содержимым с использованием методов, специфичных для Mozilla.
Эта статья написана как для начинающих, так и для разработчиков среднего уровня подготовки. Предполагается, что у читателя есть базовые знания по XUL и JavaScript. Возможно вы захотие прочитать некоторые вводные документы по DOM, такие как статья Об объектной модели документа или вводная страница Gecko DOM Reference.
Как вы знаете, XUL — это язык, основанный на XML, который использовался в различных приложениях, основанных на Mozilla, таких как Firefox и Thunderbird, для описания пользовательского интерфейса. В XUL приложениях JavaScript объявляет поведение, используя DOM APIs для доступа к XUL документу.
Так что же такое Document Object Model APIs?
Это интерфейсы, которые используются при любом взаимодействии скрипта и документа. Если вы когда-либо писали скрипт, который взаимодействует с XUL (или HTML) документом, то вы уже использовали DOM-вызовы. Пожалуй, наиболее известным DOM методом является document.getElementById()
, который возвращает элемент с заданным id
. Возможно, вы использовали и другие DOM-вызовы, такие как element.setAttribute()
, или, если вы писали расширения, метод addEventListener()
. Все они объявлены в DOM.
Существуют также DOM-методы, которые создают, перемещают или удаляют элементы из документа. Они будут продемонстрированы позже в этом параграфе. А сейчас давайте поймем, что такое document.
Document — это структура данных, которой можно управлять через DOM APIs. Логической структурой каждого объекта document является дерево с узлами-элементами, атрибутами, комментариями и т.д. Используйте инструмент DOM Inspector, чтобы увидеть древовидное представление любого объекта document.
Можно считать, что document — это представление в памяти правильного HTML или хорошо сформированного XML, как, например, xhtml или XUL.
Важно запомнить, что разные страницы (и даже различные экземпляры одной страницы) соответствуют разным документам. Каждое XUL-окно имеет имеет свой собственный отдельный document. Более того, в одном окне может быть несколько различных объектов document, если используется <iframe>
, <browser>
или <tabbrowser>
. Вы должны быть уверены, что все время управляете именно тем (а не иным) объектом document (больше информации можно найти в разделе Working with windows in chrome code). Если ваш скрипт подключается с использованием тэга <script>
, то свойство document
ссылается на DOM document, который содержит скрипт.
Этот параграф демонстрирует использование DOM-методов appendChild()
, createElement()
, insertBefore()
, и removeChild()
.
Этот пример удаляет все элементы, дочерние для элемента с id=someElement
из текущего document'а, с использованием метода removeChild()
который удаляет первый дочерний элемент до тех пор, пока их не останется совсем.
Заметьте, что hasChildNodes()
и firstChild
являются также частью DOM API.
var element = document.getElementById("someElement"); while(element.hasChildNodes()){ element.removeChild(element.firstChild); }
Этот пример добавляет два новых элемента меню к <menupopup>
: в начало и в конец. Здесь используется метод document.createElementNS()
для создания элементов и insertBefore()
с appendChild()
для вставки созданных xml элементов в документ.
Замечания:
document.createElementNS()
создает элемент, но не добавляет ничего в document. Необходимо воспользоваться другим DOM-методом, таким как appendChild()
для вставки только что созданного элемента в document.appendChild()
добавляет узел после других узлов, а insertBefore()
вставляет узел перед узлом, указанным во втором параметре.function createMenuItem(aLabel) {
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
var item = document.createElementNS(XUL_NS, "menuitem"); // Создаем новый элемент меню XUL
item.setAttribute("label", aLabel);
return item;
}
var popup = document.getElementById("myPopup"); // элемент <menupopup>
var first = createMenuItem("First item");
var last = createMenuItem("Last item");
popup.insertBefore(first, popup.firstChild);
popup.appendChild(last);
Вы также можете использовать appendChild()
и insertBefore()
для передвигания существующих элементов. Например, вы можете подвинуть элемент "First item" в конец popup'а, добавив эту строчку последней:
popup.appendChild(first);
Этот оператор удалит узел из его текущего места и заново вставит его в конец popup'а.
XBL — это язык, используемый в Mozilla для объявления новых виджетов. Виджеты, объявленные в XBL можно выбирать для объявления некоторого содержимого, объединенного в связку с помощью граничного элемента. Такое содержимое называется анонимное содержимое и оно не доступно через обычную модель DOM. (подкорректируйте, я не понял смысла).
Вместо этого вам необходимо использовать методы интерфейса nsIDOMDocumentXBL
. Например:
// Выбирает первый анонимный дочерний элемент для заданного document.getAnonymousNodes(node)[0]; // Возвращает NodeList анонимных элементов с атрибутом anonid равным el1 document.getAnonymousElementByAttribute(node, "anonid", "el1");
См. getAnonymousNodes и getAnonymousElementByAttribute в XBL-справочнике.
Если вы достали анонимный узел, то дальше можно использовать обычные DOM-методы для работы с остальными элементами этой связки.