В AS3 какое свойство (свойства) определяет, может ли InteractiveObject получить фокус сцены с помощью щелчка мыши?
В AS3 stage.focus получает / устанавливает экранный объект с фокусом. Фокус может быть назначен любому экземпляру InteractiveObject и любому наследующему его объекту, например TextFields, Sprites и MovieClips.
Между прочим, я посмотрел, было ли что-то из этого частью спецификации ECMAScript (поскольку у AS3 и JavaScript есть это общее), и узнал, что в JavaScript управлять фокусом (в частности, его извлечением) гораздо сложнее; Старые браузеры не поддерживают свойство document.activeElement, и даже более новые браузеры ограничиваются возвратом только элементов, связанных с вводом. Если ни один такой элемент не имеет фокуса, все основные браузеры возвращают элемент body - кроме IE 9, который возвращает элемент html, Chrome 26 возвращает false в документах XHTML, но, очевидно, вы можете использовать document.querySelector(':focus').
В отличие от JavaScript, я обнаружил, что AS3 очень однороден и последовательн в том, что любой InteractiveObject может получить фокус клавиатуры; однако объекты (кроме экземпляров TextField и SimpleButton) по умолчанию не получают фокус при взаимодействии с мышью или клавиатурой.
Когда я впервые прикрепил прослушиватель событий к сцене и прослушал событие FocusEvent.FOCUS_IN, оно не сработало, когда я щелкнул объект MovieClip, созданный на сцене, что привело меня к выводу, что MovieClips/Sprites/InteractiveObjects делают не получают фокус сцены по умолчанию при нажатии или вкладке.
Между тем, если я установлю для свойств tabEnabled или buttonMode значение true, событие срабатывает при щелчке объекта. Между прочим, в документации для tabEnabled говорится, что это автоматически имеет значение true, когда Sprite.buttonMode имеет значение true, поэтому tabEnabled представляется интересным свойством (кроме того, buttonMode включает другие функции, такие как запуск событий нажатия клавиш при нажатии клавиш ввода или пробела, когда объект имеет фокус).
Мне просто интересно, является ли tabEnabled правильным способом гарантировать, что интерактивный объект получает фокус сцены при нажатии. Хотя в документации для tabEnabled говорится, что это приводит к тому, что объект включается в порядок вкладок [клавиатура], в нем, в частности, не упоминается взаимодействие с мышью и не упоминается какое-либо общее состояние, такое как "может получить фокус". Кажется, что любому интерактивному объекту можно назначить фокус вручную, установив stage.focus для этого объекта.
Правильно ли, что свойство tabEnabled InteractiveObject является основным свойством, которое контролирует, можно ли назначать фокус посредством взаимодействия с помощью клавиатуры и мыши?
В JavaScript спецификация HTML5 устанавливает более сложную последовательность условий, которые должны быть выполнены, чтобы объект считался "фокусируемым": "Элемент является фокусируемым, если выполнены все следующие условия: 1. Флаг фокуса элемента tabindex имеет вид set. 2. Элемент либо визуализируется, либо является потомком элемента canvas, представляющего внедренный контент. 3. Элемент не является инертным. * Элемент не отключен."
ОБНОВЛЕНИЕ: После более тщательной проверки, хотя AS3 не имеет общего свойства "enabled", кажется, что "mouseEnabled" функционирует аналогично, поскольку при значении false экземпляр не получает никаких событий мыши (или других событий пользовательского ввода, таких как клавиатура) События)."
ОБНОВЛЕНИЕ до первого обновления: документация ошибочна, так как включает фразу "(или другие события пользовательского ввода, например события клавиатуры)", потому что сфокусированные объекты по-прежнему получают события нажатия клавиши "вверх / вниз", несмотря на то, что mouseEnabled имеет значение false.
3 ответа
Как вы и предполагали, это свойство tabEnabled, которое необходимо установить, чтобы гарантировать, что InteractiveObject может получить фокус через пользовательский ввод, но для ясности я немного расширю свой ответ:
Любой InteractiveObject может иметь фокус, независимо от его свойств. Тем не менее, есть несколько свойств, которые определяют, как получить фокус и где фокус.
- Stage.focus указывает, какой InteractiveObject имеет фокус, прямо сейчас; Этот метод не только для чтения, и установка его переключает фокус на данный InteractiveObject; Полезно программно изменить способ обработки фокуса в вашем приложении.
- InteractiveObject.tabEnabled позволяет экземпляру получать фокус с помощью действий пользователя; что означает щелчок, вкладку и использование клавиш со стрелками. Обратите внимание, что это свойство не позволяет экземпляру получать вводимые пользователем данные; это только позволяет Сцене дать фокус этому экземпляру.
- InteractiveObject.tabIndex позволяет устанавливать порядок вкладок с помощью анимации. Это относится только к табуляции; используя клавиши со стрелками игнорировать это.
- InteractiveObject.mouseEnabled не имеет никакого отношения к фокусу. Это позволяет экземпляру получать события мыши.
Чтобы лучше понять, как фокусировка работает в AS3, можно сказать, что объект не получает фокус, ему дан фокус. Фокусом управляет Стадия, а tabEnabled - это индикатор, чтобы Стадия знала, должен ли он давать фокус объекту или нет.
Приложение: свойство tabEnabled по умолчанию имеет значение false, поскольку AS3 оценивает, что большинству InteractiveObject не требуется фокус. В конце концов, объект может получать клики без необходимости фокусировки.
Я знаю, что это старый вопрос, но я изучал переключение фокуса в течение некоторого времени, так как у клиента был новый запрос. Они хотели, чтобы клавиша + на цифровой клавиатуре действовала как вкладка и изменяла фокус между текстовыми полями.
То, как я достиг этого, было с помощью некоторых хитростей, которые я установил в первые дни программирования.
Я написал функцию, которая генерирует текстовые поля (ниже):
function mkText(xpos,ypos,h,w,l:int,multi,sel,bor:Boolean,borCol:uint):TextField{
var textInput = new TextField();
textInput.x = xpos;
textInput.y = ypos;
textInput.height = h;
textInput.width = w;
textInput.maxChars = l;
textInput.multiline = multi;
textInput.selectable = sel;
textInput.border = bor;
textInput.borderColor = borCol;
addChild(textInput);
return textInput;
}
Благодаря этому я могу создавать текстовые поля в цикле с массивом, например так:
for(var i:int=0;i<8;i++)
{
cForm[i] = mkText(cFormXpos,cFormYpos,27,69,2,false,true,true,0x000000);
cForm[i].type = TextFieldType.INPUT;
cForm[i].restrict = "0-9";
cForm[i].defaultTextFormat = txFormat;
cFormYpos += cForm[i].height + 13;
}
Каждый запуск цикла создаст новое текстовое поле с динамически назначенным именем экземпляра, которое вы можете проверить, отслеживаете ли вы имя какого-либо элемента массива, например, instance1, instance2 и т. Д. На каждое из них может ссылаться их расположение в массиве, и даже пакетное форматирование или ссылки по отдельности. При таком подходе я использовал инкремент и общий атрибут stage.focus для переключения между ними.
function keyBind(e:KeyboardEvent)
{
if(e.keyCode == 107)
{
stage.focus = cForm[tabOrder];
if(tabOrder < 8)
{
tabOrder++;
}
else
{
tabOrder = 0;
}
}
}
Я понимаю, что это несколько грубое решение более сложной проблемы, но назначенные индексы облегчают работу в режиме табуляции.
Надеюсь, это поможет.
ура
пс. извините за любые тонкие орфографические ошибки. Я набрал это довольно быстро, и мне пришлось редактировать несколько раз.
Я уже отметил другой пост в качестве ответа, но я просто хотел добавить дополнительную информацию.
FocusEvent.MOUSE_FOCUS_CHANGE и FocusEvent.KEY_FOCUS_CHANGE предшествуют событиям FOCUS_IN и FOCUS_OUT и могут быть отменены, в отличие от событий FOCUS_IN/OUT.
Что еще более важно, как целевой, так и связанные объекты заполняются (т. Е. Не являются нулевыми) в событии MOUSE_FOCUS_CHANGE, тогда как непосредственно следующее событие FOCUS_OUT будет иметь нулевой связанный объект, если значение tabEnabled выбранного объекта было ложным.
Обрабатывая события MOUSE_FOCUS_CHANGE и KEY_FOCUS_CHANGE в фазе захвата на сцене, вы можете переопределить поведение по умолчанию всей системы с изменением фокуса и даже не допустить, чтобы фокус стал нулевым в результате щелчка мыши.
Например, поведение по умолчанию при щелчке по объекту (независимо от того, является ли tabEnabled истинным или ложным), относится к событию MOUSE_FOCUS_CHANGE, которое включает объект, который в данный момент имеет фокус, а также объект, по которому щелкнули. Тогда условно:
- Если выбранный объект имеет tabEnabled = true, тогда ему будет назначен фокус, а события FOCUS_OUT/IN будут заполнены как целевыми, так и связанными объектами.
- Если, с другой стороны, объект, по которому щелкнули, имеет tabEnabled = false, тогда фокус устанавливается на ноль, а событие FOCUS_OUT будет иметь нулевой связанный объект.
Поэтому, если вы отмените поведение по умолчанию, которое зависит от значения tabEnabled, вы можете просто выбрать всегда вручную назначать фокус связанному объекту, несмотря на то, что tabEnabled имеет значение false, поэтому щелчки мыши по-прежнему будут вызывать события FOCUS_OUT, но они будут никогда не иметь нулевого связанного объекта.
Точно так же вы можете переопределить поведение по умолчанию для изменений фокуса, вызванных клавиатурой. Мой обработчик событий KEYBOARD_FOCUS_CHANGE основан на классе, который поддерживает пригодный для растаскивания стек для пользовательских массивов циклов фокусировки, поэтому при нажатии клавиши Tab проверяется, находится ли текущий фокусированный объект в активном цикле в верхней части стека (или является дочерний элемент / внук объекта в активном цикле), и если это так, он назначает фокус на объект в следующей позиции индекса (или предыдущей, если клавиша Shift нажата). Если объект не находится в цикле, он (на основе настройки) автоматически назначает фокус первому объекту в активном цикле, который оказывается на вершине стека. Это может даже предотвратить выход фокуса из цикла (объект фокуса должен находиться в цикле или быть потомком объекта в цикле). Цикл может быть изменен с помощью открытых методов и ему могут быть назначены предварительно определенные наборы элементов управления, так как диалоговые окна с различными наборами элементов управления открываются и закрываются. Когда вы помещаете новый массив элементов управления в стек для диалогового окна, он создает резервную копию текущего фокусированного объекта и текущего массива фокуса, а затем перемещает фокус в новый массив. Когда вы выталкиваете стек, он восстанавливает старый массив и возвращает фокус на объект, который имел фокус при резервном копировании. Все это работает очень хорошо, и гораздо более точно и управляемо, чем механизм по умолчанию.
У менеджера фокуса, который я построил, даже есть свойство "nullFocus", которое позволяет вам назначить конкретный объект как объект, который должен иметь фокус, когда в противном случае фокус становится нулевым, гарантируя, что фокус никогда не будет на самом деле нулевым, а события всегда обрабатываются,