Управление кнопками при помощи клавиатуры

Flash позиционируется компанией Macromedia, прежде всего, как инструмент для разработки интерфейсов web-узлов. Хорошая техника создания Flash-сайта (да и любого приложения) подразумевает, что все характерные для более традиционных технологий принципы usability (удобства использования) будут в нем соблюдены. В частности, это означает, что должна существовать возможность навигации по управляющим элементам не при помощи мыши, ас использованием клавиатуры.

Особенностью HTML-страниц является то, что с ними можно абсолютно полноценно работать, даже если у компьютера нет мыши. Нажимая клавишу , можно последовательно обойти все элементы, являющиеся ссылками, а также различные меню и формы. Обход осуществляется начиная от положения, занимаемого текстовым курсором, в порядке слева направо и сверху вниз. Изменить последовательность обходу на противоположную можно, нажимая не , а + . О выделенном при клавиатурном обходе элементе говорят, что он помещен в фокус. Визуально фокус отображается в виде тонкой рамки, описанной вокруг объекта. Чтобы задействовать ссылку, помещенную в фокус, нужно нажать . Навигация по меню и формам, находящимся в фокусе, осуществляется при помощи клавиш движения.

Был период, когда Flash как инструмент разработки сайтов жестко критиковался за несоответствие созданных сего помощью страниц важнейшим принципам usability.


И одним из изъянов полных Flash-страниц называлась невозможность навигации по ним при помощи клавиатуры. Во Flash MX эта проблема (равно как и многие другие недостатки, связанные с несоответствием правилам usability) была преодолена введением возможности клавиатурного обхода элементов swf-фильма.

Вид кнопки, находящейся в фокусе Важной особенностью клавиатурного обхода является то, что он не может быть осуществлен при помощи клавиши , если фильм проигрывается в среде тестирования Flash (однако обход в обратном направлении, проводимый сочетанием +, возможен всегда). Это связано с тем, что в ней данная клавиша является зарезервированной. Чтобы отключить поддержку горячих клавиш, активизируйте настройку Disable Keyboard Shortcuts меню Control среды тестирования.

Многократное нажатие клавиши для перехода к нужному элементу — это не самый эффективный подход, если в фильме имеется значительное число кнопок или текстовых полей. Гораздо лучше использовать для навигации клавиши движения. При этом можно перейти от элемента к элементу за меньшее количество шагов.

При наведении на кнопку фокуса она переходит в режим Over. Чтобы ее нажать, нужно задействовать клавишу или клавишу пробела (в среде тестирования можно использовать только пробел).


При этом срабатывают сразу два события — onPress и onReleasc (это связано с тем, что на практике данные события вполне взаимозаменяемы, и оба они используются, если необходимо среагировать на нажатие кнопки).

Ограничений на время существования фокуса не имеется. Однако он сразу же исчезает, когда в движение приходит мышь. Если после этого восстановить режим : обхода, то в фокус будет взят элемент, следующий за тем, на котором предыдущий ; обход оборвался. Идеальный объект для отработки принципов клавиатурной навигации — это созванный нами в Проекте 2 калькулятор. Откройте его и попытайтесь осуществить несколько арифметических операций, используя только клавиатуру.

Помешать в фокус и обходить при помощи клавиши можно не только кнопки, но и текстовые поля

Динамическое наведение фокуса
Как вы уже знаете, чтобы навести на кнопку фокус, нужно войти в режим клавиатурного обхода и перейти к нужному объекту при помощи клавиш движения или нескольких последовательных нажатий клавиши . Однако иногда необходимо помещать элемент в фокус динамически. В таких случаях нужно использовать метод setFocus(path) объекта Selection, где path — путь к кнопке.

Для примера создадим метод класса Button, предназначенный для наведения на кнопку фокуса:

Button.prototype.setFocus = function():Void {
Selection.setFocus(this);
};

Динамически удалить фокус можно, передав методу setFocus() значение null.

Определить, какой экземпляр в данный момент находится в фокусе, можно, обратившись к методу Selection.getFocus().


Данный метод возвращает путь к выделенной кнопке. Если режим клавиатурного обхода не активизирован, то возвращается null.

Особенностью метода getFocus() является то, что он возвращает путь к кнопке, даже если она фактически потеряла фокус в результате движения мыши.

Свойство _focusrect
При наведении на кнопку фокуса она отображается в ярко-желтой рамке. Это не всегда удобно. Так, вполне вероятно, что рамка фокуса совершенно не будет вписываться в общий дизайн интерфейса (например, если он выполнен в мягких серых тонах, то желтый прямоугольник будет излишне контрастировать с остальными объектами). В таких случаях отображение лучше отключать.

Для этого нужно использовать специальное свойство _focusrect.

Свойство _focusrect принимает булево значение: true — желтая рамка фокуса отображается, false — помещение на кнопку фокуса будет проявляться только ее переходом в режим Over. По умолчанию свойство _focusrect всегда равно true.

Во Flash 5 свойство _focusrect было глобальным, т. е. оно задавало режим отображения желтой рамки сразу для всех объектов в фильме. Начиная со Flash MX данный режим может настраиваться индивидуально для каждой кнопки, клипа или текстового поля.


Однако если _focusrect выступает как свойство основной временной диаграммы, то оно интерпретируется как глобальное. При этом оно перекрывает все сделанные локально настройки.

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

События onSetFocus и onKillFocus
У класса Button имеется два события, полезных при работе с фокусом:

• onSetFocus. Происходит при наведении на кнопку фокуса. В качестве аргумента функции-обработчику события onSetFocus передается путь к объекту, находившемуся в фокусе ранее.

Если данная кнопка была помещена в фокус первой, то этот аргумент равен null. Событие onSetFocus не возникает, если кнопка получает фокус два раза подряд (в частности, это возможно, если данный экземпляр является единственным выделяемым объектом).

• onKillFocus. Возникает, если кнопка теряет фокус. Функции-обработчику этого события в качестве аргумента передается путь к объект, получившему фокус. Если фокус кнопка потеряла не в результате его перевода на новый элемент, то данный аргумент равен null. Особенностью события onKillFocus является то, что оно не происходит, если фокус пропадает в результате движения мыши.

Обратите внимание, что события onSetFocus и onKillFocus — это практически единственные события в ActionScript, обработчикам которых передаются аргументы.


Второе отличие указанных событий от большинства событий кнопок заключается в том, что их обработчики не могут быть заданы в стиле Flash 5 при помощи конструкции on(event).

События onSetFocus и onKillFocus полезны, прежде всего, если при наведении на кнопку фокуса должны происходить какие-то видимые изменения. Для примера напишем функцию, позволяющую создавать вокруг использующегося в качестве кнопки клипа рамку фокуса произвольного цвета и толщины:

// Метод описывает вокруг клипа clip рамку линией толщиной thickness,
// цветом rgb, прозрачностью alpha
function newSetFocus (clip:MovieClip, thickness:Number, rgb:Number,
alpha:Number):Void {
// Читаем граничные координаты клипа clip
var coords:Object = clip.getBounds();
// Создаем клип, на котором будет рисоваться рамка
clip.createEmptyMovieClip ("hoist", 10000);
with (clip.hoist) { // Рисуем рамку нужной линией
lineStyle(thickness, rgb, alpha);
moveTo(coords.xMin, coords.yMin);
lineTo(coords.xMin, coords.yMax), lineTo (coords.xMax, coords.yMax),
lineTo(coords.xMax, coords.yMin), lineTo(coords-xMin, coords.yMin);
// Если мышь начнет двигаться, рамка фокуса должна быть удалена
clip.holst.onMouseMove = function{):Void {
_root.newKillFocus(clip);
};
}
}
// Функция, удаляющая рамку фокуса с клипа clip
function newKillFocus(clip:MovieClip):Void {
clip.holst.renroveMovieClip();
};
// Создаем клип любого вида и называем его mov
// Клип с обработчиком "кнопочного" события ведет себя как кнопка
mov.onPress = function():Void {
trace ("Кнопка нажата!");
};
mov._focusrect = false; // Отключаем отображение желтой рамки фокуса
mov.onSetFocus = function():Void { // При наведении на клип фокуса рисуем
// вокруг него рамку
newSetFocus(this, 3, 0xAAAAAA, 100);
};
mov.onKillFocus = function():Void { // При снятии фокуса рамку удаляем
newKillFocus(this);
};

Набрав приведенный код, вы увидите, что создаваемые им рамки фокуса ничем не уступают «обычным». Однако их вид можно задавать так, чтобы они идеально подходили под цветовую гамму интерфейса. Существенный же недостаток у функции newSetFocus один: она может быть применена только к клипам.

Задание маршрута клавиатурного обхода
По умолчанию все кнопки, текстовые поля, клипы с обработчиками «кнопочных» событий включаются в клавиатурный обход, осуществляемый при помощи клавиши ( + ) или клавиш движения. Это не всегда приемлемо. Например, клип может использовать «кнопочное» событие, однако по выполняемым функциям кнопкой не являться. В этом случае включать его в число обходимых элементов нет никакого смысла.

За включение объекта в список элементов, подлежащих клавиатурному обходу, отвечает свойство tabEnabled. Если оно не определено (равно undefined) или равно true, то экземпляр обходиться будет. Если же tabEnabled присвоить значение false, то соответствующий элемент будет исключен из числа обходимых.

Изначально свойство tabEnabled не существует. Поэтому его значение по умолчанию равно
undefined. Навести, нажимая <ТаЬ>, фокус на экземпляр, свойство tabEnabled которого установлено в false, будет, естественно, невозможно. Однако это можно сделать программно, используя метод Selection.setFocus().

Если свойство tabEnabled клипа, имеющего обработчики «кнопочных» событий, равно false, то для обхода будут доступны элементы его внутренней структуры. Если же клип сам является обходимым, то включить в цепочку клавиатурного обхода вложенную в него кнопку, клип или текстовое поле будет невозможно. Однако это можно сделать, если подлежащий Tab-обходу клип является обычным.

При желании вы можете самостоятельно задать последовательность обхода элементов интерфейса. Для этого существует специальное свойство tabIndex. В качестве значения оно принимает порядковый номер данного объекта в очередности обхода. Это должно быть положительное целое число. Чем меньше значение tabIndex, тем раньше элемент попадет в фокус (если для обхода используется не клавиша <ТаЬ>, а сочетание + , то очередность будет обратной). Важно следить, чтобы значение tabIndex для каждого элемента было уникальным. Иначе некоторые из них обходиться не будут.

Явное задание списка элементов, подлежащих клавиатурному обходу, при помощи tabIndex блокирует обход не вошедших в него объектов. Так, достаточно для одной кнопки в фильме задать свойство tabIndex, чтобы все остальные сделались не выделяемыми. Свойство tabEnabled имеет приоритет над tablndex: если первое установлено в false, то элемент не будет выделяться при клавиатурном обходе, даже если второе имеет конкретное значение.

Особенности клавиатурного обхода и программного фокуса в случае клипов
Изначально клипы не входят в число объектов, подлежащих клавиатурному обходу. Исключение представляют экземпляры, имеющие обработчики «кнопочных» событий. Такие клипы считаются кнопками и поэтому являются обходимыми по умолчанию. Чтобы включить обычный клип в список обходимых объектов, его свойству tabEnabled должно быть присвоено значение true. При этом если клип содержит подлежащие обходу элементы, то вначале ь фокус будет помещен он сам, а лишь затем объекты его внутренней структуры (в случае клипов-кнопок вложенные элементы обходятся в том случае, если свойству tabEnabled клипа положено значение false).

Обычно если клип сам является обходимым элементом, то проводиться обход вложенных в него объектов не должен. Конечно, можно сделать их не выделяемыми при помощи свойства enabled или явно задать список подлежащих клавиатурному обходу элементов, используя свойство tabIndex. Однако можно поступить и проще. Чтобы указать, что объекты внутренней структуры клипа обходиться не должны, его свойству tabChildren должно быть присвоено значение false. По умолчанию данное свойство равно undefined (т. е. оно попросту не существует). В этом случае, а также если tabChildren равно true, вложенные в клип объекты будут обходимыми.

Как вы помните, в ActionScript объект может получить фокус не только в результате клавиатурного обхода, но и программно, при помощи метода Selection.setFocus(), Если клип не имеет обработчиков кнопочных событий, то выделить его подобным образом по умолчанию будет невозможно.

Чтобы это сделать, предварительно необходимо присвоить специальному свойству focusEnabled клипа значение true.

Величина свойства focusEnabled никак не влияет на то, будет ли клип выделяться при клавиатурном обходе элементов фильма. Оно задает лишь возможность программного наведения на него фокуса с использованием метода Selection.setFocus().

Оцените статью: (0 голосов)
0 5 0

Статьи из раздела Action Script на эту тему:
Клипы как кнопки
Отключение кнопок
Режим элемента меню
События кнопок

Вернуться в раздел: Action Script / 11. Кнопки