Россия, Звенигород |
Первые элементы управления и темы
4.3. Кнопки XUL
XUL предоставляет несколько тегов, так или иначе связанных с кнопками. Два из них отвечают большинству требований: <button> и <toolbarbutton>. Для создания кнопок редко требуются какие-то другие теги. Тем не менее, есть еще три тега, достойные упоминания: <autorepeatbutton>, <thumb> и <scrollbarbutton>. Эти пять тегов наиболее похожи на кнопки из всех XUL-тегов. Некоторые из них включают несколько типов кнопок.
Есть еще большое количество других тегов, имитирующих кнопки. Теги grippy создают элементы, похожие на кнопки и присоединяющиеся к другим элементам управления. У тега <label> тоже есть несколько свойств, присущих кнопкам. <statusbarpanel> рассматривается не здесь, а в "Навигация" , "Навигация". Наконец, некоторых тегов следует избегать из-за их незавершенности или устаревания.
4.3.1. Пять основных кнопок
XUL-теги для создания кнопок определяются, как и любые другие теги, и могут включать любое содержимое:
<button><description label="Tools"/><button>
Хотя между открывающим и закрывающим тегом может быть помещено любое содержимое, Mozilla не все сочетания кнопок и содержимого отображает корректно. Цель XUL 1.0 - создать функциональный XML-язык для графических интерфейсов. Это значит, что все очевидные сочетания "кнопка-содержимое" будут работать, но поддержка более редких сочетаний - это уж как повезет. Самый простой способ узнать, будет ли конкретное содержимое тега отображаться нормально внутри кнопки - проверить практически.
На рисунке 4.4 показаны эти пять кнопок, каждая в трех состояниях: обычном, при наведении мышки и в нажатом состоянии. Пустое место означает, что данное состояние не подразумевает смены внешнего вида кнопки.
На рисунке 4.4 содержимое каждой кнопки - всего лишь тег <description>, как и в предыдущем примере в одну строчку. Каждая из кнопок выглядит и ведет себя отлично от остальных. Менее очевиден тот факт, что и внутренняя обработка каждой кнопки тоже разная. Немного забегая вперед, скажем только, что каждая из них также поддерживает подмножество событий DOM 2 и, следовательно, набор обработчиков событий JavaScript. Подробнее об этом рассказано в "События" , "События".
Получение аналога рисунка 4.4 нетривиально, если пользоваться Mozilla версии 1.2.1 или более поздней. Начиная с этой версии, в теме Classic (и только в ней) реализована особая поддержка элементов управления. Она заключается в том, что такие элементы, как кнопки, будут выглядеть как стандартные кнопки операционной системы, а не как кнопки какой-либо темы Mozilla. Увидеть кнопки Mozilla можно, пользуясь более ранней версией Mozilla или переключившись из Classic в другую тему, либо отредактировав файлы этой темы. В разделе "Темы и скины" настоящей лекции описывается, как это все работает.
4.3.1.1 Тег <button>
Тег <button> - рабочая лошадка среди всех кнопок Mozilla, он эквивалентен тегу <button> в HTML. Как и положено самой сложной из всех кнопок XUL, ей доступны многие функции, отсутствующие у других кнопок:
- она может получать фокус ввода. Фокус ввода на рисунке 4.4 показан как пунктирная линия внутри границ кнопки;
- она может находиться в списке навигации, то есть у нее есть ее пронумерованная позиция в порядке перехода между элементами на странице;
- все ее содержимое автоматически заключается в невидимый тег <hbox>. На этот внешний блок могут влиять глобальные стили;
- она поддерживает службы accessibility Mozilla, что гарантирует доступность по нажатию только клавиши Tab или ее эквивалента;
- она реагирует на действия пользователя как "стандартная" кнопка: она выглядит как кнопка до, во время и после взаимодействия с пользователем.
У следующих XML-атрибутов внутри тега <button> - особое значение:
disabled checked group command tabindex image label accesskey crop
Атрибуты disabled и checked могут принимать значение true. Первый из них удаляет кнопку из списка переходов и затеняет ее внешний вид. Второй позволяет кнопке постоянно быть в нажатом состоянии. При этом атрибут checked не играет никакой роли, если значение disabled - true. На рисунке 4.5 показаны кнопки с этими атрибутами. Обратите внимание, что внешний вид кнопки с checked="true" отличен от вида нажатой кнопки на рисунке 4.4.
Атрибуты image, label, accesskey и crop относятся к содержимому <button>. <button> всегда подразумевает применение <hbox>, но если использовать кнопку без содержимого, <button/>, будет добавлено содержимое по умолчанию, которое эквивалентно во всем, за исключением стилей, листингу 4.2.
<hbox align="center" pack="center" flex="1"> <image/> <label/> </hbox>Листинг 4.2. Содержимое <button> по умолчанию
Теги <image> и <label> ничего не будут отображать, потому что у них отсутствуют атрибуты src и value. У тега <button> эту информацию предоставляют атрибуты image и label. accesskey и crop также влияют на значение label содержимого кнопки по умолчанию. Например:
<button image="green.png" label="Go" dir="rtl"/>
Кнопка, созданная этим кодом, может выглядеть так, как показано на рисунке 4.6.
Части содержимого появляются в обратном порядке потому, что присутствует атрибут dir.
Для кнопок также будет использоваться содержимое по умолчанию, если внутри присутствуют содержательные теги, но все они особые. К таким особым тегам относятся <observes>, <template>, <menupopup> и <tooltip>. Может показаться, что исключения выбраны случайно, но эти четыре тега часто используются как наполнение для <button>. В "XBL-связки" , "XBL-связки", объясняется, как читать XBL-файлы, где указаны эти исключения.
Стандартные атрибуты размещения вроде align, указанные для <button>, будут относиться к содержимому тега <hbox>. Остальные атрибуты, специфичные для <button>, упомянутые выше, можно применить и к нескольким другим XUL-тегам, а не только к кнопкам, так что они будут обсуждаться ниже, в "Формы и меню" , "Формы и меню".
Как мы увидим далее, тег <button> поддерживает почти все события из стандарта DOM 2, например, onfocus, onclick и onmouseover, а также псевдоселекторы CSS 2 вроде :active, :hover и :focus.
Что отличает <button> от определенных пользователем XUL-тегов вроде <foo>, так это внутренняя обработка. Когда пользователь нажимает на кнопку, событие нажатия завершается на теге <button>. Это нестандартная модель обработки событий для XML-документа. Стандартная обработка требует прохождения события от <button> ниже, к содержимому тега кнопки, например, к тегам <description> или <image>. В стандартной модели такое событие, несомненно, достигнет любого конкретного тега под указателем мыши, где оно может быть обработано, а затем вернется к <button>. Такого не бывает с <button> в XUL. Внутри Mozilla, в тексте кода для кнопок на C/C++, обработка событий меняется так, как если бы для всех событий тега <button> был вызван метод DOM 2 stopPropagation(). Содержимое <button> "застывает", как насекомое в янтаре - оно не получает событий вообще. Это поведение - суть тега <button>.
Чтобы увидеть, как работает эта фундаментальная функция <button>, воспользуемся следующим кодом, который реализует две вложенные кнопки:
<button><button onclick="alert('Hi')" label="B2"/></button>
Внутренняя кнопка внешне никак не будет реагировать на действия пользователя, она даже не будет "знать", что пользователь что-то сделал. Она заморожена во внешней кнопке.