PDA

Просмотр полной версии : Фазы события


goldlider
18.09.2011, 22:34
Имеется такой код
package
{
import flash.display.*;
import flash.events.*;

public class EventPhasesDispatch extends Sprite
{

public function EventPhasesDispatch():void
{
// Create theSprite
var theSprite:Sprite = new Sprite();
theSprite.graphics.lineStyle(1);
theSprite.graphics.beginFill(0x0000FF, 1);
theSprite.graphics.drawRect(0, 0, 50, 50);
theSprite.x = 320;
theSprite.y = 240;

// Create theSprite2
var theSprite2:Sprite = new Sprite();
theSprite2.graphics.lineStyle(1);
theSprite2.graphics.beginFill(0x00FF00, 1);
theSprite2.graphics.drawRect(0, 0, 25, 25);

theSprite.addChild(theSprite2);
stage.addChild(theSprite);

theSprite.stage.addEventListener(MouseEvent.CLICK, mouseClickListener, false);
}

private function mouseClickListener(e:MouseEvent):void
{
trace("Click");
}
}
}

Почему, когда в слушателе событий третий параметр стоит в true, щелкая по стейджу, в Output не выводится сообщение ?

DJDrugsounD
18.09.2011, 22:40
http://help.adobe.com/ru_RU/FlashPlatform/reference/actionscript/3/flash/events/EventDispatcher.html

goldlider
18.09.2011, 22:44
DJDrugsounD, я читал Help. И знаю, что означает параметр true в слушателе события. Мне не понятно почему stage являясь получателем события, нереагирует на событие, т.е. в моем случае не выводит сообщение Click.

Genm
18.09.2011, 23:48
http://blog.hanpo.tw/2011/01/event-flow-chart-usecapture-true-or.html
Вот тут хорошо все показано и рассказано

goldlider
19.09.2011, 23:14
Genm, спасибо за ссылку очень помогло.
Что вообще означает дословно на русском языке данное выр-е: Capture Phase of Event Flow didn't process Listener(mc) ?

Psycho Tiger
20.09.2011, 01:07
Оно означает, что подписывашись на фазу захвата сам объект-подписчик (тот, который сделал addEventListener) событие не получит.

goldlider
20.09.2011, 10:08
Psycho Tiger, я не догнал такой момент, если приемник зарегистрирован в потомке(mc) при установленом useCapture = true, и предок(stage) является получателем события. Почему предок(stage) вообще не получает уведомление о возникшем событии на фазе захвата ?

Psycho Tiger
20.09.2011, 18:15
Мне тяжело мыслить в таком ключе )
Накидайте схематично пример кодом и я скажу.

goldlider
20.09.2011, 18:25
Psycho Tiger, приведу тот же пример (http://blog.hanpo.tw/2011/01/event-flow-chart-usecapture-true-or.html), что мне показал выше Genm. На 8-ом скриншоте, почему кликая по стейджу, функция не срабатывает ?

alatar
20.09.2011, 19:24
Потому, что листенер добавлен к mc и до него событие вообще не доходит. Не важно какая фаза обрабатывается. Ситуация ничем не отличается от 6-го скриншота.

goldlider
20.09.2011, 19:35
Потому, что листенер добавлен к mc и до него событие вообще не доходит. Не важно какая фаза обрабатывается. Ситуация ничем не отличается от 6-го скриншота.

Я имел ввиду, что событие не доходит до предка, т.е. в данном случае Stage. Что же тогда получается, если так рассуждать, то listener зарегистрированный в потомке mc, не доступен для предка ? Тогда где диспетчеризация событий ?

alatar
20.09.2011, 19:42
Если вы имеете ввиду свой первый пост, то при useCapture = true и клике по stage вы не сможете поймать событие, потому что для stage, у которого вы подписались, это событие находится в target фазе.

goldlider
20.09.2011, 19:45
alatar, а как вы узнали, что Stage находится в target фазе? По идее предки получают уведомлении о возникновении события на capture фазе.

alatar
20.09.2011, 19:51
Щелкните по theSprite и вы поймаете событие в восходящей фазе, когда оно будет проходить от stage к theSprite. А при клике по stage оно никуда уже не пойдет, все, оно уже пришло.

goldlider
20.09.2011, 20:10
alatar, получается, что при клике по stage, он вообще не проходит никакие фазы?

alatar
20.09.2011, 20:12
Только target.

goldlider
20.09.2011, 20:18
alatar, у меня уже путаница пошла между моим примером и примером, что указал Genm. Насчет того, что у stage только target оно верно, ведь получателем события является stage. А мне не понятно, ситуация, когда theSprite2 яв-ся объектом-подписчиком при useCapture = true, и stage требует вызова ф-ии в target фазе.

alatar
20.09.2011, 20:23
Какая разница в каком месте программы вы подписались у stage на событие? Stage один на всех. theSprite.stage это просто ссылка, с таким же результатом вы могли написать this.stage.

goldlider
20.09.2011, 20:27
alatar, я имел ввиду theSprite2.addEventListener(). Должен сработать в target фазе для theSprite2, и в capture фазе для stage. Но запуска не происходит.

alatar
20.09.2011, 20:41
Он не может сработать в capture фазе события stage. Для этого он должен быть родителем stage. А в реальности наоборот, stage является корневым родителем для всех DisplayObject, включая root. Схема отношений показана на первой картинке в примерах.

goldlider
20.09.2011, 21:40
Он не может сработать в capture фазе события stage. Для этого он должен быть родителем stage. А в реальности наоборот, stage является корневым родителем для всех DisplayObject, включая root. Схема отношений показана на первой картинке в примерах.

Кто он ? theSprite 2 ?

alatar
20.09.2011, 21:56
Именно.

goldlider
20.09.2011, 22:00
alatar, а кто говорил, что запуск theSprite2 возможен на фазе capture. Я говорил, что theSprite2 запускается на target.

alatar
20.09.2011, 22:21
Что-то я начинаю терять смысл диалога. Соберите мысли до кучи, выдохните и попробуйте описать ситуацию.

dimarik
20.09.2011, 22:35
Оно означает, что подписывашись на фазу захвата сам объект-подписчик (тот, который сделал addEventListener) событие не получит.

Бред, бро?

Psycho Tiger
20.09.2011, 22:41
Бред, бро?
Не совсем, не точно выразился.
Перефразирую: подписавшись на capture подписки на target не будет. Сейчас сам думаю, как то что я написал было связано с моими мыслями )

dimarik
20.09.2011, 22:52
stage является корневым родителем для всех DisplayObject, включая root.

Не забываем вовремя остановиться. root есть ссылка на экземпляр DocumentClass, что, впрочем, ясно из хелпа. Этот экземпляр может быть добавлен в любую ветку списка отображения, не обязательно в Stage.

alatar
20.09.2011, 23:44
Хмм... где я написал, что root обязательно ребенок stage? Хотя возможно прозвучало двусмысленно.

goldlider
21.09.2011, 08:47
alatar, сейчас попробую объяснить, что же мне все таки непонятно. Приведу следующие примеры.

1. Почему не срабатывает handler для Stage?
// Где-то в классе

mc.addEventListener(MouseEvent.CLICK, handler, false);
click stage on screen



2. Почему не срабатывает handler для Stage?
// Где-то в классе

mc.addEventListener(MouseEvent.CLICK, handler, true);
click stage on screen


P.S. Если можно, то более подробно описать процесс передачи события от объекта к объекту и в какой фазе должен сработать handler на данных примерах. Был бы очень благодарен.

alatar
21.09.2011, 11:28
На оба вопроса: потому, что ни разу не подписались на stage.
На оба вопроса: Можно поймать событие, если подписаться у stage на capture фазу и кликнуть mc.

Во втором случае, вы поймаете событие, если кликнуть по ребенку mc.

События мыши проходят от stage (capture), по всем предкам объекта, попадают в объект, по которому кликнули (target) и спускаются обратно к stage (bubbling). Если кликнуть по stage, то событие возникнет только в stage, а так как предков у него нет, то захватывать его негде и всплывать ему некуда. Это событие можно будет поймать только в stage и, естественно, оно будет в target фазе.

goldlider
21.09.2011, 13:16
На оба вопроса: потому, что ни разу не подписались на stage.
На оба вопроса: Можно поймать событие, если подписаться у stage на capture фазу и кликнуть mc.


Вы имеете ввиду так:

stage.addEventListener(MouseEvent.CLICK, handler, true)
mc.addEventListener(MouseEvent.CLICK, handler, false);

Рассмотрим такой случай. Я изложу ход своих мыслей, а вы подправьте если я не прав.

stage.addEventListener(MouseEvent.CLICK, handler, false)
mc.addEventListener(MouseEvent.CLICK, handler, false);

function handler(e:MouseEvent):
{
trace("eventPhase : " + e.eventPhase + ", currentTarget : " + e.currentTarget.name +
", target : " + e.target.name + ", type : " + e.type);
}

Кликаем по stage в output выводит:
eventPhase : 2, currentTarget : null, target : null, type : click

Кликаем по mc в output выводит:
eventPhase : 2, currentTarget : mc, target : mc, type : click
eventPhase : 3, currentTarget : null, target : mc, type : click

Я думаю по этому поводу следующее.
Кликая по stage получателем события яв-ся stage, т.к. у stage нет предков. Что верно отображается в output, где указана, что handler запустился на target фазе. Идем дальше. Обработчик события подписанный на stage продолжает свою работу и доходит до своих потомков, т.е. до mc в bubbles фазе. На этом обработчик стейджа заканчивает свою работу. Далее кликая по mc, выполняется обработчик mc.
Он уведомляет о событии stage на capture, но handler не запускается. Далее на target фазе для mc выполняется обработчик mc. На bubbles фазе этот же handler mc делает уведомление своему предку stage о том, что mc обработал событие. На этом заканчивается работа.

alatar
21.09.2011, 13:44
Он уведомляет о событии stage на capture, но handler не запускается.
На capture фазу создается отдельных обработчик, поэтому хендлер не срабатывает.
Обработчик события подписанный на stage продолжает свою работу и доходит до своих потомков, т.е. до mc в bubbles фазе. На этом обработчик стейджа заканчивает свою работу.
Если кликнуть по stage, событие больше никуда не пойдет. bubbles фаза идет от target к stage, а не наоборот.
Далее кликая по mc, выполняется обработчик mc.
Он уведомляет о событии stage на capture, но handler не запускается. Далее на target фазе для mc выполняется обработчик mc. На bubbles фазе этот же handler mc делает уведомление своему предку stage о том, что mc обработал событие. На этом заканчивается работа.
Сначала выполнится обработчик на stage, если он с useCapture = true. Потом обработик mc в target фазе. Потом обработчик на stage (bubbles фаза), если он с useCapture = false.

goldlider
21.09.2011, 14:01
Сначала выполнится обработчик на stage, если он с useCapture = true. Потом обработик mc в target фазе. Потом обработчик на stage (bubbles фаза), если он с useCapture = false.

Если у обработчика stage useCapture = true, то и обработчик stage и обработчик mc сработают в target фазе.
Если у обработчика stage useCapture = false, то сработают одновременно оба обработчика, вначале mc на target, затем stage на bubbles. Не так ли ?

alatar
21.09.2011, 15:02
Не совсем.
package
{
import flash.display.Graphics;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.EventPhase;
import flash.events.MouseEvent;

[SWF(width="1024", height="768")]

public class ABCTest extends Sprite
{
public function ABCTest()
{
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;

var mc:Sprite = new Sprite();
draw(mc.graphics);

addChild(mc);

mc.addEventListener(MouseEvent.CLICK, mc_clickHandler);
stage.addEventListener(MouseEvent.CLICK, stage_clickHandler, true);
stage.addEventListener(MouseEvent.CLICK, stage_clickHandler);
}

private function mc_clickHandler(event:MouseEvent):void
{
trace("mc click");
}

private function stage_clickHandler(event:MouseEvent):void
{
switch (event.eventPhase)
{
case EventPhase.AT_TARGET:
trace("stage target phase");
break;
case EventPhase.CAPTURING_PHASE:
trace("stage capturing phase");
break;
case EventPhase.BUBBLING_PHASE:
trace("stage bubbling phase");
break;
}
}

private function draw(g:Graphics):void
{
g.beginFill(0xFFFF00);
g.drawRect(0,0,100,100);
g.endFill();
}
}
}

Кликаем по stage. В консоли
stage target phase
Кликаем по mc. В консоли
stage capturing phase
mc click
stage bubbling phase