Март 2011

Руководство по actionscript. часть 2, стр. 061

Рассмотрим описанные шаги на примере с кнопкой-переключателем. Предположим, мы используем нашу кнопку-переключатель в приложении с панелью управления, которое назначает различные привилегии своим пользователям в зависимости от их статуса. Пользователи-«гости» могут использовать только некоторые

кнопки на панели, в то время как пользователям-«администраторам» доступны все кнопки.

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

Для упрощения будем считать, что кнопку-переключатель можно включить или выключить только щелчком кнопки мыши (не используя клавиатуру). Всякий раз, когда пользователь щелкает на кнопке-переключателе, выполняется диспетчеризация события ToggleEvent. TOGGLE_ATTEMPT. Затем, если никакой приемник не отменяет стандартного поведения, мы изменяем состояние переключателя. Рассмотрим соответствующий код:

private function clickListener (e:MouseEvent):void { // Пользователь попытался включить или выключить переключатель, поэтому // просим среду Flash выполнить диспетчеризацию события // ToggleEvent. TOGGLE_ATTEMPT. получателем которого является данный объект // ToggleSwitch. Сначала создадим событийный объект… var toggleEvent:ToggleEvent =

new ToggleEvent(ToggleEvent. TOGGLE_ATTEMPT. true, true);

// … затем отправляем запрос на диспетчеризацию события dispatchEvent(toggleEvent);

// Диспетчеризация события Toggl eEvent. TOGGLE_ATTEMPT завершена. // Если никакой приемник не отменил стандартное поведение события… if (ItoggleEvent. isDefaultPrevented( )) {

// …изменяем состояние переключателя

toggle( );

}

}

В нашем приложении с панелью управления мы регистрируем приемник события ToggleEvent. TOGGLE_ATTEMPT для каждого объекта ToggleSwitch. Внутри этого приемника проверяется статус пользователя. Для закрытых переключателей, если пользователь является «гостем», мы отменяем стандартное поведение события. Рассмотрим этот код:

// Приемник выполняется всякий раз. когда возникает событие // ToggleEvent. TOGGLE_ATTEMPT

private function toggleAttemptListener (e:ToggleEvent):void { // Если пользователь является «гостем»… if (userType == UserType. GUEST) {

// …запретить изменение состояния переключателя

e. preventDefaultC );

В листинге 12.5 целиком показан код приложения с панелью управления, включая полнофункциональную, хотя и простую графическую версию кнопки-переключателя. Понять этот код вам помогут подробные комментарии.

Руководство по actionscript. часть 2, стр. 062

Листинг 12.5. Классы приложения с панелью управления

// Класс ToggleEvent package { import flash. events.*;

// Класс, представляющий пользовательское событие «toggle» public class ToggleEvent extends Event {

// Константа для типа события «toggle»

public static const TOGGLE:String = «toggle»;

// Константа для типа события «toggleAttempt»

public static const TOGGLE_ATTEMPT:String = «toggleAttempt»;

// Обозначает текущее состояние переключателя -// включен или выключен public var isOn:Boolean;

// Конструктор

public function ToggleEvent (type:String.

bubbles’.Boolean = false.

cancelable:Boolean = false.

isOn:Boolean = false) { // Передаем параметры конструктора в конструктор суперкласса super(type, bubbles, cancelable);

// Запоминаем состояние переключателя, которое может быть использовано // в приемниках события ToggleEvent. TOGGLE this. isOn = isOn;

}

// Любой класс пользовательского события должен переопределить // метод clone( )

public override function clone( )’.Event { return new ToggleEvent(type, bubbles, cancelable. isOn);

}

// Любой класс пользовательского события должен переопределить // метод toString( )

public override function toString( ):String { return formatToString(«ToggleEvent». «type», «bubbles».

Руководство по actionscript. часть 2, стр. 063

«cancelable». «eventPhase». «isOn»);

}

}

// Класс ToggleSwitch package {

import flash. display.*; import flash. events.*;

// Представляет простую кнопку-переключатель со стандартным поведением public class ToggleSwitch extends Sprite {

// Запоминает состояние переключателя.

private var isOn:Boolean;

// Содержит графическое изображение кнопки-переключателя private var icon.-Sprite;

// Конструктор

public function ToggleSwitch ( ) { // Создаем объект Sprite, который будет содержать графическое // изображение кнопки-переключателя icon = new Sprite( ); addChild(icon);

// По умолчанию переключатель выключен isOn = false; drawOffState( );

// Регистрируем приемник для получения уведомлений всякий раз.

Советы web-дизайнеру

Каждый специалист имеет свои секреты, который он применяет в своей работе. Так и дизайнеры имеют свои маленькие секреты.
Вот некоторые из них:
1. Использование изображений должно быть оправдано, они должны быть дополнением в тему, а не лишь бы что влепить;
2. В изображении должно максимальное значение соотношения качество-размер; Прочитать остальную часть записи »

Руководство по actionscript. часть 2, стр. 064

// Если пользователь щелкнет кнопкой мыши

// на графическом изображении переключателя

icon. addEventLi stener(MouseEvent. CLICK, cli ckLi stener);

}

// Приемник, выполняемый после щелчка кнопкой мыши // на кнопке-переключателе

private function clickListener (e:MouseEvent):void { // Пользователь попытался включить или выключить переключатель. // поэтому просим среду Flash выполнить диспетчеризацию // события ToggleEvent. TOGGLE_ATTEMPT. получателем которого // является данный объект ToggleSwitch. Сначала создадим // событийный объект… var toggleEvent:Toggl eEvent =

new ToggleEvent(ToggleEvent. TOGGLE_ATTEMPT. true, true);

// …затем отправляем запрос на диспетчеризацию события dispatchEvent(toggleEvent);

// Диспетчеризация события ToggleEvent. TOGGLE_ATTEMPT завершена. // Если никакой приемник не отменил стандартное поведение события… if (!toggleEvent. isDefaultPrevented( )) {

// …изменяем состояние переключателя

toggle( );

}

}

// Включает переключатель, если в настоящий момент он выключен, или

// выключает его. если переключатель включен. Стоит отметить, что состояние

// переключателя может быть изменено программным путем, даже если пользователь // не имеет привилегий изменить состояние переключателя вручную, public function toggle ( ):void {

// Изменяем состояние переключателя

isOn = IisOn;

// Рисуем для нового состояния переключателя соответствующее изображение if (isOn) {

drawOnState( ); } else {

drawOffState( );

}

// Просим среду Flash выполнить диспетчеризацию события // ToggleEvent. TOGGLE, получателем которого является данный // объект ToggleSwitch

var toggleEvent:ToggleEvent = new ToggleEvent(ToggleEvent. TOGGLE.

Руководство по actionscript. часть 2, стр. 065

True, false. isOn);

dispatchEvent(toggleEvent);

}

// Рисуем изображение для выключенного состояния private function drawOffState ( ):void {

icon. graphics. clear( );

icon. graphics. lineStyle(l);

icon. graphics. beginFill(OxFFFFFF);

icon. graphics. drawRect(0. 0. 20. 20);

}

// Рисуем изображение для включенного состояния private function drawOnState ( ):void {

icon. graphics. clear( );

i con. g raphi cs.1i neSty1e(1);

icon. graphics. beginFill(OxFFFFFF);

icon. graphics. drawRect(0. 0. 20. 20);

icon. graphics. beginFill(0×000000);

icon. graphics. drawRect(5. 5. 10. 10);

}

}

}

// Класс Control Panel (основной класс приложения) package { import flash. display.*;

// Базовое приложение, которое демонстрирует отмену // стандартного поведения для пользовательских событий public class ControlPanel extends Sprite {

// Присваиваем уровень привилегий для пользователя данного приложения.

Руководство по actionscript. часть 2, стр. 066

// В данном примере только пользователи с привилегиями UserType. ADMIN

// могут использовать кнопку-переключатель.

private var userType:int = UserType. GUEST;

// Конструктор

public function Control Panel ( ) { // Создаем объект ToggleSwitch var toggleSwitch:ToggleSwitch = new ToggleSwitch( ); // Регистрируем приемник для событий // ToggleEvent. TOGGLE_ATTEMPT

toggleSwi tch. addEventLi stener(ToggleEvent. TOGGLE_ATTEMPT.

toggleAttemptListener);

// Регистрируем приемник для событий ToggleEvent. TOGGLE toggleSwi tch. addEventLi stener(ToggleEvent. TOGGLE,

toggleListener); // Добавляем кнопку-переключатель в иерархию отображения // данного объекта addChi1dCtoggleSwitch);

}

// Приемник выполняется всякий раз. когда возникает событие // ToggleEvent. TOGGLE_ATTEMPT

private function toggleAttemptListener (e:ToggleEvent):void { // Если пользователь является «гостем»… if (userType == UserType. GUEST) {

// …запретить изменение состояния переключателя

e. preventDefault( );

}

}

// Приемник выполняется всякий раз. когда возникает событие // ToggleEvent. TOGGLE

private function toggleListener (e:ToggleEvent):void { if (e. isOn) {

traceC’The ToggleSwitch is now on.»); } else {

trace(«The ToggleSwitch is now off.»);

}

}

}

// Класс UserType package {

// Определяет константы, представляющие уровни // пользовательских привилегий в приложении // с панелью управления public class UserType {

public static const GUEST:int =0;

public static const ADMIN:int = 1;

}

} •

Теперь, когда мы познакомились с пользовательскими событиями в ActionScript, рассмотрим две последние темы, связанные с событиями.

Руководство по actionscript. часть 2, стр. 067

Недостаток проверки типов

в событийной модели языка ActionScript

Событийная модель ActionScript, основанная на приемниках, включает несколько различных участников: приемник события, объект, регистрирующий этот приемник, получатель события, событийный объект и имя события. Диспетчеризация определенного события (и его обработка) завершится успешно только в том случае, если все участники будут надлежащим образом взаимодействовать между собой. Для этого должны выполняться следующие основные условия.

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

? Должен существовать сам приемник.

? Приемник должен знать, как обрабатывать событийный объект, передаваемый в процессе диспетчеризации возникшего события.

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

Когда приемник регистрируется в объекте для получения события, он вступает в соглашение, основанное на типах данных, которое гарантирует выполнение первых трех условий. Если это соглашение не выполняется, компилятор генерирует ошибку типа. Например, рассмотрим следующий код, описывающий и регистрирующий приемник, в котором умышленно допущены три нарушения (выделенные полужирным шрифтом) контракта приемника события:

urlLoader. addEventLi stener(Event. COMPLTE, completeLi stenr);

private function completeListener (e:MouseEvent):void { traceCLoad complete»);

}

В приведенном коде нарушения контракта приемника события заключаются в следующем.

? Константа Event. COMPLTE записана с ошибкой: пропущена буква Е. Компилятор сгенерирует ошибку, которая предупредит программиста о том, что тип события, для получения которого пытается зарегистрироваться приемник, не существует.

Руководство по actionscript. часть 2, стр. 068

? Название приемника события записано с ошибкой: пропущена еще одна буква е. Компилятор сгенерирует ошибку, которая предупредит программиста о том, что регистрируемый приемник не существует.

? Типом данных первого параметра, передаваемого в метод completeListener ( ), является Мои s еЕ ve n t, который не соответствует типу данных событийного объекта для события Event. COMPLETE. На этапе диспетчеризации события среда выполнения Flash сгенерирует ошибку, которая предупредит программиста, что приемник не может обработать переданный в него событийный объект.

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

^ I Соглашение между приемником события и объектом, который регистрирует этот при-d, m емник, основанное на типах данных, позволяет гарантировать корректное выполнение нашего кода, обрабатывающего события.

Тем не менее соглашение между приемником и объектом, регистрирующим этот приемник, имеет один недостаток: оно не гарантирует, что объект поддерживает указанный тип события. Например, рассмотрим следующим код, который регистрирует приемник в объекте urlLoader для событий TextEvent. TEXT_INPUT:

url Loader. addEventLi stener (TextEvent. TEXTJNPUT. text InputLi stener);

Хотя с практической точки зрения у нас есть все основания полагать, что объект URLLoader никогда не будет получателем события TextEvent. TEXT_INPUT, приведенный код не вызовет ошибки. В языке ActionScript регистрация приемников для событий осуществляется по любому имени. Например, следующий бессмысленный код также является допустимым:

urlLoader. addEventLi stener(«dlrognw», dlrognwLi stener);

Каким бы очевидным ни казалось то, что объект urlLoader никогда не будет получателем события с именем 11 dl rognw «, программа на самом деле может выполнить диспетчеризацию такого события. Это демонстрирует следующий код:

urlLoader. dispatchEvent(new Event(«dlrognw»));

Учитывая, что программа имеет возможность назначать любой объект в качестве получателя любого события, язык ActionScript намеренно не использует концепцию «поддерживаемых событий». Подобная гибкость является предметом споров, поскольку она может привести к трудновыявляемым ошибкам в коде. Например, предположим, что мы используем класс Loader для загрузки внешнего изображения, как показано в следующем коде:

var loader:Loader = new Loader( );

1oader.1oad(new URLRequest(«i mage. jpg»)):

Предположим также, что объект loader будет являться получателем событий, информирующих о завершении загрузки изображения (во многом аналогично тому, как объект URLLoader является получателем событий о завершении загрузки элемента). Таким образом, мы пытаемся обработать событие Event. COMPLETE для нашего загружаемого элемента, зарегистрировав приемник непосредственно в объекте Loader, как показано в следующем коде:

1oader. addEventLi stener(Event. COMPLETE. completeLi stener);

Запустив код, мы будем удивлены, поскольку, даже несмотря на отсутствие ошибок, метод completeListener ( ) не был вызван ни разу. Так как никаких ошибок не возникло, мы не сможем сразу же определить источник проблемы в нашем коде. Последующий анализ и отладка кода будут стоить нам времени и, по всей вероятности, значительного неудовлетворения. Только прочитав соответствующий раздел документации корпорации Adobe, мы определим проблему: объекты Loader на самом деле не являются получателями событий о завершении загрузки; вместо этого события о завершении загрузки должны обрабатываться

экземпляром класса Loaderlnf о каждого объекта Loader, как показано в следующем коде:

1oader. contentLoaderInfо. addEventLi stener(Event. COMPLETE. completeLi stener);

В будущем язык ActionScript, возможно, позволит классам перечислять события, которые они поддерживают, и генерировать соответствующие предупреждения компилятора на попытки зарегистрировать приемник на события, которые не поддерживаются данным классом. Пока же классы, которые реализуют пользовательские события, путем переопределения метода addEventListener ( ) могут самостоятельно генерировать пользовательские ошибки в тех случаях, когда программа пытается зарегистрировать приемник для неподдерживаемых событий, как показано в следующем коде:

public override function addEventListener(eventType:String.

Руководство по actionscript. часть 2, стр. 069

Handler:Function, capture:Boolean = false, priority:int = 0. weakRef:Boolean = false):void { // Метод canDispatchEv. entC ) (не показан) проверяет наличие // указанного типа eventType в списке поддерживаемых // данным классом событий и возвращает значение типа Boolean. // которое говорит о том. является ли указанный тип eventType // поддерживаемым типом событий if(canDispatchEvent(eventType)) { // Событие поддерживается, поэтому приступаем к регистрации super. addEventListener(eventType. handler, capture, priority. weakRef); } else {

// Событие не поддерживается, поэтому генерируем ошибку throw new ErrorCthis + » does not support events of type ‘» + eventType + );

}

}

Мораль этой истории такова: будьте особенно внимательны при регистрации приемника для события. Всегда убеждайтесь в том, что объект, в котором регистрируется приемник, на самом деле поддерживает требуемое событие.

Теперь рассмотрим последний вопрос, касающийся событийной модели: обработку событий в приложениях, состоящих из нескольких SWF-файлов, которые размещены в различных интернет-доменах. Для изучения следующего раздела необходимс иметь общее представление о методах загрузки SWF-файлов, которые рассматриваются в гл. 28.

Обработка событий между границами зон безопасности

В гл. 19 будет рассмотрено несколько сценариев, в которых ограничения безопас ности не позволяют одному SWF-файлу осуществлять кросс-скриптинг (управ лять программным путем) над другим файлом. Когда два SWF-файла не могу]

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

? Приемники событий из одного SWF-файла не могут регистрироваться для событий в объектах другого SWF-файла.

? Если получателем события является объект в иерархии отображения, любые объекты, недоступные в SWF-файле объекта получателя, не включаются в цепочку диспетчеризации событий.

К счастью, описанные ограничения можно полностью обойти с помощью статического метода allowDomain ( ) класса flash. system. Security. Рассмотрим два примера, которые демонстрируют применение метода allowDomain ( ) для обхода каждого из этих ограничений.

*«, _

*« Информацию по загрузке SWF-файлов можно найти в гл. 28.



Полезные ссылки
Случайные записи
  • 23.01.2011">Руководство по actionscript. часть 1, стр. 044
  • 18.05.2010">Самоучитель по креативному веб-дизайну. Книга 2, стр.94
  • 11.05.2010">Самоучитель по креативному веб-дизайну. Книга 1, стр.43
  • 19.08.2010">Веб-дизайн и реклама
  • 15.01.2010">Flash сайты
  • 17.05.2010">Самоучитель по креативному веб-дизайну. Книга 2, стр.111
  • 08.03.2011">Руководство по actionscript. часть 4, стр. 077
  • 28.02.2011">Руководство по actionscript. часть 6, стр. 007
  • 31.07.2011">Выбери свой онлайн-фоторедактор
  • 18.05.2010">Самоучитель по креативному веб-дизайну. Книга 2, стр.64
  • 07.03.2011">Руководство по actionscript. часть 4, стр. 114
  • 07.01.2010">Кинетическая типографика
  • 09.03.2011">Руководство по actionscript. часть 4, стр. 057
  • 13.11.2012">Китай снял блокаду сервисов Google
  • 21.03.2011">Руководство по actionscript. часть 2, стр. 053
Опрос

Какие цвета вы предпочитаете?

View Results

Loading ... Loading ...