WonHada.com으로 이전

이벤트에 대해 알아보아요~ 본문

플래시/플렉스[Flash/Flex]

이벤트에 대해 알아보아요~

반주부 2007. 11. 15. 12:17
반응형


AS 2.0까지 초급자 기본 유의사항(?)이었던 한마디가 생각나는군요..

"버튼 내에 들어 있는 버튼은 더 이상 버튼이 아니다."

즉, 버튼 안에 버튼을 넣으면 동작을 안 한다는 거죠..가장 상위 버튼만 동작합니다..

그러나 AS 3.0 에 와서는 그 말이 더 이상 효력이 없어졌는데요..바로 'Document Object Model (DOM) Level 3' 이벤트가 적용되었기 때문입니다..
[Document Object Model (DOM) Level 3 Events Specification]
http://www.w3.org/TR/2003/NOTE-DOM-Level-3-Events-20031107/

DOM 3는 아래 그림에서 보는 바와 같이 세가지 phase로 동작합니다..

사용자 삽입 이미지













Capture Phase[EventPhase.CAPTURING_PHASE=1] : 이벤트가 발생하는 실제 오브젝트를 잡는 단계입니다.
Target Phase[EventPhase.AT_TARGET=2] : 실제 오브젝트를 잡은 단계입니다.
Bubbling Phase[EventPhase.BUBBLING_PHASE=3] : target부터 위로 이벤트가 발생합니다. 말 그대로 버블이죠..거품이 부글부글~^^

우선 이벤트를 사용한 간단한 예를 한번 볼까요..구조는 AA 내부에 BB가 있고 그 내부에 CC가 있습니다..

적용된 코드는 다음과 같습니다..
======================================================
aa.addEventListener(MouseEvent.MOUSE_OVER, on_Over1);
aa["bb"].addEventListener(MouseEvent.MOUSE_OVER, on_Over2);
aa["bb"]["cc"].addEventListener(MouseEvent.MOUSE_OVER, on_Over3);

function on_Over1(e:MouseEvent):void {
 txt.appendText("aa" + "\n");
}
function on_Over2(e:MouseEvent):void {
 txt.appendText("bb, ");
}
function on_Over3(e:MouseEvent):void {
 txt.appendText("cc, ");
}
======================================================

AA -> BB -> CC 순서대로 마우스를 이동해 보세요..그럼 다음과 같은 결과가 나옵니다..

======================================================
aa
bb, aa
cc, bb, aa
======================================================

AS 2.0이었으면 말도 안되는 결과죠? 왜냐면 버튼 내부의 버튼이 동작하고 있기 때문이죠..
그런데 한가지 궁금한게 생기네요..가장 상위 버튼부터 AA > BB > CC 인데 왜 cc, bb, aa 순으로 이벤트가 발생한 걸까요?
그 이유는 바로 위 그림에서 봤던 Target 과 Bubbling 단계에서 이벤트를 발생시켰기 때문입니다..

순서는 대략 이렇죠..

1. 마우스가 오버됩니다..
2. 가장 상위인 stage부터 root를 지나 실제 오브젝트를 찾아냅니다..이 오브젝트가 target이 되죠..(핸들러 함수에서 e.target으로 알아낼 수 있습니다)
3. 이제 target을 찾았으니 부글부글 위로 올라옵니다..바로 Bubbling이 일어나는거죠..

Target은 우리가 봤을때 가장 위에 놓은 녀석이라고 생각하면 됩니다..가장 위에서 감싸고 있는것이 아닌 가장 위에 보이는 객체죠..
그럼 여기서 알 수 있는 것이 있죠? 바로 이벤트 리스너의 기본 이벤트 발생 단계는 2와 3 즉, Target 과 Bubbling 이라는 것입니다..

그렇다면, Capture 단계에서는 이벤트가 발생할 수 없을까요?
^^ 당연히 있습니다..addEventListener() 메소드를 살펴보면..

public override function addEventListener(type:String, listener:Function,
useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void

세번째 매개변수에 useCapture가 있죠? 기본이 false 입니다..즉, true로 해주면 Capture 단계에서도 이벤트를 발생할 수 있다는 것입니다..

위 코드에서 이벤트 리스너 부분만 변경해 보면..
======================================================
aa.addEventListener(MouseEvent.MOUSE_OVER, on_Over1, true);
aa["bb"].addEventListener(MouseEvent.MOUSE_OVER, on_Over2, true);
aa["bb"]["cc"].addEventListener(MouseEvent.MOUSE_OVER, on_Over3, true);
======================================================

결과는..

======================================================
aa
aa
bb,
======================================================

이해되시나요? AA에 오버됬을때는 Capture 없이 바로 Target이기 때문에 아무 이벤트도 발생하지 않고 BB에 오버되면 AA에서 Capture 가 발생, CC에 오버되면 AA와 BB가 발생하게 되죠..

모든  Phase에서 다 발생시키고 싶다면..이벤트 리스너를 두개 생성합니다..

aa.addEventListener(MouseEvent.MOUSE_OVER, on_Over1);
aa.addEventListener(MouseEvent.MOUSE_OVER, on_Over1, true);

그럼 Target 또는 Bubbling 에서만 이벤트를 발생시키고 싶다면? 아래와 같이 핸들러 함수에서 제어가 가능합니다..

======================================================
function on_Over2(e:MouseEvent):void {
 if (e.eventPhase == 2) {//이렇게 하면 Target 단계에서만 이벤트가 발생합니다.
  txt.appendText("bb, ");
 }
}
======================================================

끝으로, 마우스 이벤트 중 MouseEvent.MOUSE_OVER 와 MouseEvent.ROLL_OVER가 있는거 아시죠? 둘의 차이는 Bubbling 의 단계에서 이벤트가 발생하느냐 안하느냐의 차이입니다..

둘 중 어떤게 발생할까요? 오늘의 문제입니다^^

이 밖에도 event propagation에 대한 부분이 있으니 공부해 보세염..원하는 때에 이벤트를 중단할 수도 있답니다^^









반응형