본문 바로가기

Flex

이벤트의 흐름 (Event Flow) 제어하기


이벤트는 캡쳐-타겟-버블의 흐름을 탄다고 이전 포스트 (2010/02/10 - [Flex/Event] - Flex 이벤트의 전파단계와 버블링 ) 에서 이야기 했었다.

이번에는 이전 포스트의 마지막에 예를 들었던 특정 Event Phase 에서만 이벤트를 받는 것과 이벤트의 흐름을 끊는 것에 대해서 알아보자.



언제나 그렇듯이 백문이 불여일견 이라고 동작하는걸 보는쪽이 이해가 확실히 빠르다.

캔버스 세개에 MouseEvent.CLICK 을 받을 수 있는 리스너가 붙어있고 이벤트가 들어오면 오른쪽 텍스트에어리어에 뿌려주도록 되어있다.

useCapture All 체크 박스는 이전 예제와 동일하다. useCapture가 true 일때 이벤트가 이벤트가 어떻게 들어오는지 확인 하는 용도로 사용 하면 된다.

redCanvasStopEvent가 체크되어있지 않은 상태로 클릭을 하게 되면.
redCanvas - blueCanvas - blackCanvas 순서로 이벤트가 전파 되는것을 알수 있다.
체크를 하고 redCanvas 클릭하게 되면.
redCanvas 에서만 이벤트를 받고 이후의 이벤트는 전파되지 않는다.

이것은 redCanvas 이벤트핸들러 함수에 event.stopPropagation() 함수가 실행되기 때문이다.
이 함수는 이벤트의 전파를 막는다. 따라서 이벤트가 버블링 되지 않고 빨간색 캔버스에서 끝나버리는 것이다.

redCanvasStopEvent 를 체크 해제 하고 '블루 캔버스가 타겟일때만' 이라고 되어있는 체크박스를 체크상태로 만든 후에 빨간색 캔버스를 클릭해보자.

이벤트가 redCanvas - blackCanvas 로 전파되는 것을 볼수 있다.
파란색 캔버스의 핸들러 함수에 e.eventPhase == 2 일때만 실행 하도록 조건이 붙어있기 때문이다.

파란색 캔버스를 클릭하게 되면 정상적으로 이벤트를 받았다는 메시지가 출력될 것이다.
이전 포스트에서 이야기 했듯이.. 어떤 방법으로 이벤트를 걸러내서 원하는 이벤트만 받아서 사용할 것인지는 그때 그때 프로젝트의 상황에 맞춰서 잘 골라야 한다.

stopPropagation과 stopImmediatePropagation의 차이

두가지 다 이벤트를 멈춘다는 점에서는 동일하다.
하지만 차이가 있는데 말로 해서는 뭔소린지 잘 모르겠으니 예제를 보자.

blueCanvas 에는 리스너가 하나 붙어있고 redCanvas 에는 리스너가 두개가 붙어있다.
redClick1 함수에는 라디오버튼의 선택 상황에 따라서 stopPropagation과 stopImmediatePropagation 을 할것인지에 대한 조건문이 있다.

private function addListener():void
{
	blueCanvas.addEventListener(MouseEvent.CLICK, blueClick);
	redCanvas.addEventListener(MouseEvent.CLICK, redClick1);
	redCanvas.addEventListener(MouseEvent.CLICK, redClick2);
}






빨간색 캔버스가 클릭 되면 이벤트는 red1 - red2 - blue 순서로 활성화되는 것을 볼 수 있다.
stopPropagation 을 선택하고 클릭 해보면 red1 - red2 까지는 활성화 되지만 blue로 이벤트가 전파 되지는 않는다.
stopImmediatePropagation 선택하는 경우에는 red1 에서 끝나버린다.

둘다 멈추는것은 동일 하지만 전자는 currentTarget의 이벤트까지는 유지 해주게 되고. 후자는 모든 이벤트 플로우를 중단하게 된다.
(ps. 둘의 차이를 말로 명확하게 설명할 수 있는 분이 있으면 꼭 댓글을 남겨주세요 -ㅅ-;;)

이것의 차이도 target 과 currentTarget 의 차이 처럼 미묘하게 버그를 유발 할수 있으니 신경 써서 사용해야 할것이다.

이벤트의 흐름제어는 복잡한 UI 를 만들거나 Drag & Drop 같은것을 구현할때에 빈번하게 쓰이게 된다.
한번쯤은 고민 해보고 사용하는 것이 좋을 것이다.