1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
---
title: Динамически изменяемый пользовательский интерфейс на XUL
slug: Динамически_изменяемый_пользовательский_интерфейс_на_XUL
tags:
- DOM
- Extensions
- XUL
---
<p>В этой статье обсуждается управление <a href="/ru/XUL" title="ru/XUL">XUL</a> интерфейсами с использованием <a href="/ru/DOM" title="ru/DOM">DOM</a> и других API. Здесь объясняется принцип <em>документов</em> DOM, приводится несколько простых примеров использования вызовов DOM для выполнения простейших манипуляций с документом, после чего приводится пример, демонстрирующий работу с <em>анонимным <a href="/ru/XBL" title="ru/XBL">XBL</a> содержимым</em> с использованием методов, специфичных для Mozilla.</p>
<p>Эта статья написана как для начинающих, так и для разработчиков среднего уровня подготовки. Предполагается, что у читателя есть базовые знания по XUL и JavaScript. Возможно вы захотие прочитать некоторые вводные документы по DOM, такие как статья <a href="/ru/Об_объектной_модели_документа" title="ru/Об_объектной_модели_документа">Об объектной модели документа</a> или <a href="/ru/Gecko_DOM_Reference/Introduction" title="ru/Gecko_DOM_Reference/Introduction">вводная страница</a> <a href="/ru/Gecko_DOM_Reference" title="ru/Gecko_DOM_Reference">Gecko DOM Reference</a>.</p>
<h3 id=".D0.92.D0.B2.D0.B5.D0.B4.D0.B5.D0.BD.D0.B8.D0.B5" name=".D0.92.D0.B2.D0.B5.D0.B4.D0.B5.D0.BD.D0.B8.D0.B5">Введение</h3>
<p>Как вы знаете, <a href="/ru/XUL" title="ru/XUL">XUL</a> — это язык, основанный на <a href="/ru/XML" title="ru/XML">XML</a>, который использовался в различных приложениях, основанных на Mozilla, таких как Firefox и Thunderbird, для описания пользовательского интерфейса. В XUL приложениях <a href="/ru/JavaScript" title="ru/JavaScript">JavaScript</a> объявляет поведение, используя <a href="/ru/Gecko_DOM_Reference" title="ru/Gecko_DOM_Reference">DOM APIs</a> для доступа к XUL документу.</p>
<p>Так что же такое <strong>D</strong>ocument <strong>O</strong>bject <strong>M</strong>odel APIs?</p>
<p>Это интерфейсы, которые используются при любом взаимодействии скрипта и документа. Если вы когда-либо писали скрипт, который взаимодействует с XUL (или HTML) документом, то вы уже использовали DOM-вызовы. Пожалуй, наиболее известным DOM методом является <code><a href="/ru/DOM/document.getElementById" title="ru/DOM/document.getElementById">document.getElementById()</a></code>, который возвращает элемент с заданным <code>id</code>. Возможно, вы использовали и другие DOM-вызовы, такие как <code><a href="/ru/DOM/element.setAttribute" title="ru/DOM/element.setAttribute">element.setAttribute()</a></code>, или, если вы писали расширения, метод <code><a href="/ru/DOM/element.addEventListener" title="ru/DOM/element.addEventListener">addEventListener()</a></code>. Все они объявлены в DOM.</p>
<p>Существуют также DOM-методы, которые создают, перемещают или удаляют элементы из документа. Они будут продемонстрированы позже в этом параграфе. А сейчас давайте поймем, что такое <em>document</em>.</p>
<h3 id=".D0.A7.D1.82.D0.BE_.D1.82.D0.B0.D0.BA.D0.BE.D0.B5_document.3F" name=".D0.A7.D1.82.D0.BE_.D1.82.D0.B0.D0.BA.D0.BE.D0.B5_document.3F">Что такое document?</h3>
<p>Document — это структура данных, которой можно управлять через DOM APIs. Логической структурой каждого объекта document является дерево с узлами-элементами, атрибутами, комментариями и т.д. Используйте инструмент <a href="/ru/DOM_Inspector" title="ru/DOM_Inspector">DOM Inspector</a>, чтобы увидеть древовидное представление любого объекта document.</p>
<p>Можно считать, что document — это представление в памяти правильного HTML или хорошо сформированного XML, как, например, xhtml или XUL.</p>
<p>Важно запомнить, что разные страницы (и даже различные экземпляры одной страницы) соответствуют разным документам. Каждое XUL-окно имеет имеет свой собственный отдельный document. Более того, в одном окне может быть несколько различных объектов document, если используется <code><a href="/ru/XUL/iframe" title="ru/XUL/iframe"><iframe></a></code>, <code><a href="/ru/XUL/browser" title="ru/XUL/browser"><browser></a></code> или <code><a href="/ru/XUL/tabbrowser" title="ru/XUL/tabbrowser"><tabbrowser></a></code>. Вы должны быть уверены, что все время управляете именно тем (а не иным) объектом document (больше информации можно найти в разделе <a href="/ru/Working_with_windows_in_chrome_code" title="ru/Working_with_windows_in_chrome_code">Working with windows in chrome code</a>). Если ваш скрипт подключается с использованием тэга <code><a href="/ru/XUL/script" title="ru/XUL/script"><script></a></code>, то свойство <code>document</code> ссылается на DOM document, который содержит скрипт.</p>
<h3 id=".D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80:_.D0.98.D1.81.D0.BF.D0.BE.D0.BB.D1.8C.D0.B7.D0.BE.D0.B2.D0.B0.D0.BD.D0.B8.D0.B5_.D0.BC.D0.B5.D1.82.D0.BE.D0.B4.D0.BE.D0.B2_DOM" name=".D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80:_.D0.98.D1.81.D0.BF.D0.BE.D0.BB.D1.8C.D0.B7.D0.BE.D0.B2.D0.B0.D0.BD.D0.B8.D0.B5_.D0.BC.D0.B5.D1.82.D0.BE.D0.B4.D0.BE.D0.B2_DOM">Пример: Использование методов DOM</h3>
<p>Этот параграф демонстрирует использование DOM-методов <code><a href="/ru/DOM/element.appendChild" title="ru/DOM/element.appendChild">appendChild()</a></code>, <code><a href="/ru/DOM/document.createElement" title="ru/DOM/document.createElement">createElement()</a></code>, <code><a href="/ru/DOM/element.insertBefore" title="ru/DOM/element.insertBefore">insertBefore()</a></code>, и <code><a href="/ru/DOM/element.removeChild" title="ru/DOM/element.removeChild">removeChild()</a></code>.</p>
<h4 id=".D0.A3.D0.B4.D0.B0.D0.BB.D0.B5.D0.BD.D0.B8.D0.B5_.D0.B2.D1.81.D0.B5.D1.85_.D0.B4.D0.BE.D1.87.D0.B5.D1.80.D0.BD.D0.B8.D1.85_.D1.8D.D0.BB.D0.B5.D0.BC.D0.B5.D0.BD.D1.82.D0.BE.D0.B2" name=".D0.A3.D0.B4.D0.B0.D0.BB.D0.B5.D0.BD.D0.B8.D0.B5_.D0.B2.D1.81.D0.B5.D1.85_.D0.B4.D0.BE.D1.87.D0.B5.D1.80.D0.BD.D0.B8.D1.85_.D1.8D.D0.BB.D0.B5.D0.BC.D0.B5.D0.BD.D1.82.D0.BE.D0.B2">Удаление всех дочерних элементов</h4>
<p>Этот пример удаляет все элементы, дочерние для элемента с id=<code>someElement</code> из текущего document'а, с использованием метода <code><a href="/ru/DOM/element.removeChild" title="ru/DOM/element.removeChild">removeChild()</a></code> который удаляет первый дочерний элемент до тех пор, пока их не останется совсем.</p>
<p>Заметьте, что <code><a href="/ru/DOM/element.hasChildNodes" title="ru/DOM/element.hasChildNodes">hasChildNodes()</a></code> и <code><a href="/ru/DOM/element.firstChild" title="ru/DOM/element.firstChild">firstChild</a></code> являются также частью DOM API.</p>
<pre class="eval">var element = document.getElementById("someElement");
while(element.hasChildNodes()){
element.removeChild(element.firstChild);
}
</pre>
<h4 id=".D0.92.D1.81.D1.82.D0.B0.D0.B2.D0.BA.D0.B0_.D1.8D.D0.BB.D0.B5.D0.BC.D0.B5.D0.BD.D1.82.D0.BE.D0.B2_.D0.B2_.D0.BC.D0.B5.D0.BD.D1.8E" name=".D0.92.D1.81.D1.82.D0.B0.D0.B2.D0.BA.D0.B0_.D1.8D.D0.BB.D0.B5.D0.BC.D0.B5.D0.BD.D1.82.D0.BE.D0.B2_.D0.B2_.D0.BC.D0.B5.D0.BD.D1.8E">Вставка элементов в меню</h4>
<p>Этот пример добавляет два новых элемента меню к <code><a href="/ru/XUL/menupopup" title="ru/XUL/menupopup"><menupopup></a></code>: в начало и в конец. Здесь используется метод <code><a href="/ru/DOM/document.createElementNS" title="ru/DOM/document.createElementNS">document.createElementNS()</a></code> для создания элементов и <code><a href="/ru/DOM/element.insertBefore" title="ru/DOM/element.insertBefore">insertBefore()</a></code> с <code><a href="/ru/DOM/element.appendChild" title="ru/DOM/element.appendChild">appendChild()</a></code> для вставки созданных xml элементов в документ.</p>
<p>Замечания:</p>
<ul>
<li><code><a href="/ru/DOM/document.createElementNS" title="ru/DOM/document.createElementNS">document.createElementNS()</a></code> создает элемент, но не добавляет ничего в document. Необходимо воспользоваться другим DOM-методом, таким как <code><a href="/ru/DOM/element.appendChild" title="ru/DOM/element.appendChild">appendChild()</a></code> для вставки только что созданного элемента в document.</li>
<li><code><a href="/ru/DOM/element.appendChild" title="ru/DOM/element.appendChild">appendChild()</a></code> добавляет узел после других узлов, а <code><a href="/ru/DOM/element.insertBefore" title="ru/DOM/element.insertBefore">insertBefore()</a></code> вставляет узел перед узлом, указанным во втором параметре.</li>
</ul>
<pre class="eval">function createMenuItem(aLabel) {
const XUL_NS = "<span class="nowiki">http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul</span>";
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);
</pre>
<p>Вы также можете использовать <code><a href="/ru/DOM/element.appendChild" title="ru/DOM/element.appendChild">appendChild()</a></code> и <code><a href="/ru/DOM/element.insertBefore" title="ru/DOM/element.insertBefore">insertBefore()</a></code> для передвигания существующих элементов. Например, вы можете подвинуть элемент "First item" в конец popup'а, добавив эту строчку последней:</p>
<pre class="eval">popup.appendChild(first);
</pre>
<p>Этот оператор удалит узел из его текущего места и заново вставит его в конец popup'а.</p>
<h3 id=".D0.90.D0.BD.D0.BE.D0.BD.D0.B8.D0.BC.D0.BD.D0.BE.D0.B5_.D1.81.D0.BE.D0.B4.D0.B5.D1.80.D0.B6.D0.B8.D0.BC.D0.BE.D0.B5_.28XBL.29" name=".D0.90.D0.BD.D0.BE.D0.BD.D0.B8.D0.BC.D0.BD.D0.BE.D0.B5_.D1.81.D0.BE.D0.B4.D0.B5.D1.80.D0.B6.D0.B8.D0.BC.D0.BE.D0.B5_.28XBL.29">Анонимное содержимое (XBL)</h3>
<p><a href="/ru/XBL" title="ru/XBL">XBL</a> — это язык, используемый в Mozilla для объявления новых виджетов. Виджеты, объявленные в XBL можно выбирать для объявления некоторого содержимого, объединенного в связку с помощью граничного элемента. Такое содержимое называется <em>анонимное содержимое</em> и оно не доступно через обычную модель DOM. <span class="comment">(подкорректируйте, я не понял смысла</span>).</p>
<p>Вместо этого вам необходимо использовать методы интерфейса <code><a href="/ru/NsIDOMDocumentXBL" title="ru/NsIDOMDocumentXBL">nsIDOMDocumentXBL</a></code>. Например:</p>
<pre class="eval">// Выбирает первый анонимный дочерний элемент для заданного
document.getAnonymousNodes(node)[0];
// Возвращает NodeList анонимных элементов с атрибутом anonid равным el1
document.getAnonymousElementByAttribute(node, "anonid", "el1");
</pre>
<p>См. <a href="/ru/XBL/XBL_1.0_Reference/DOM_Interfaces#getAnonymousNodes" title="ru/XBL/XBL_1.0_Reference/DOM_Interfaces#getAnonymousNodes">getAnonymousNodes</a> и <a href="/ru/XBL/XBL_1.0_Reference/DOM_Interfaces#getAnonymousElementByAttribute" title="ru/XBL/XBL_1.0_Reference/DOM_Interfaces#getAnonymousElementByAttribute">getAnonymousElementByAttribute</a> в XBL-справочнике.</p>
<p>Если вы достали анонимный узел, то дальше можно использовать обычные DOM-методы для работы с остальными элементами этой связки.</p>
<h3 id=".D0.A1.D0.BC.D0.BE.D1.82.D1.80.D0.B8_.D1.82.D0.B0.D0.BA.D0.B6.D0.B5" name=".D0.A1.D0.BC.D0.BE.D1.82.D1.80.D0.B8_.D1.82.D0.B0.D0.BA.D0.B6.D0.B5">Смотри также</h3>
<ul>
<li><a href="/ru/XUL_Tutorial/Document_Object_Model" title="ru/XUL_Tutorial/Document_Object_Model">A related chapter on DOM</a></li>
<li><a href="/ru/XUL_Tutorial/Modifying_a_XUL_Interface" title="ru/XUL_Tutorial/Modifying_a_XUL_Interface">XUL Tutorial:Modifying a XUL Interface</a></li>
</ul>
|