최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday

티스토리 뷰

플래시 작업중 2중으로 객체가 마우스 오버, 아웃이벤트를 가지고있을경우

 

밑에 있던 객체는 마우스 포커스를 잃어 자연스레 마우스 아웃이 진행된다.

 

아래 샘플과 같이 main_mc안에 under_mc, close_mc가 들어있고

 

under_mc에서 close_mc로 마우스를 가져가면 under_mc 부분은 마우스아웃이 진행되어 오버 효과가 풀리게된다.

 

플래시 작업할때 의외로 많은 고민과 애로사항이 있는 부분이다.

 

이것을 relateObject라는 이벤트로 캐치해낸뒤 약간의 조건문으로 해결할 수 있다.

 

문제점)

 


 

 

APi를 보면

 

relatedObject:InteractiveObject

 

이벤트와 관련된 표시 목록 객체에 대한 참조입니다.

 

예를 들어 mouseOut 이벤트가 발생하면 relatedObject는 포인팅 장치가 현재 가리키고 있는 표시 목록 객체를 나타냅니다.

 

이 속성은 mouseOut, mouseOver, rollOut 및 rollOver 이벤트에 적용됩니다.

 

라고 나와있다.

 

 


 

 

해결1. 조건문으로 간소화 처리)


import flash.events.MouseEvent;
import caurina.transitions.Tweener;
import caurina.transitions.properties.ColorShortcuts;
ColorShortcuts.init();

main_mc.under_mc.buttonMode = true;
main_mc.close_mc.buttonMode = true;

main_mc.under_mc.addEventListener(MouseEvent.MOUSE_OVER, overHan);
main_mc.under_mc.addEventListener(MouseEvent.MOUSE_OUT, underOutHan);

main_mc.close_mc.addEventListener(MouseEvent.MOUSE_OVER, overHan);
main_mc.close_mc.addEventListener(MouseEvent.MOUSE_OUT, closeOutHan);

function overHan(e:MouseEvent):void{
 Tweener.addTween(e.target, {_color:"0x0066ff", time:1});
}

function underOutHan(e:MouseEvent):void{
 
 var container:MovieClip = e.currentTarget.parent as MovieClip;
 var relate:Object = e.relatedObject;
 
 if(relate != null){ //null체크를 안해주면 relate.name 속성에 접근할 수 없어서 에러가난다.
  if(relate.name == "close_mc")return;
 }
          
 Tweener.addTween(e.target, {_color:null, time:1});
}

function closeOutHan(e:MouseEvent):void{
 Tweener.addTween(e.target, {_color:null, time:1});
}


22 : relate변수에 타겟이 바뀐 e.relateObject를 받은뒤

24 : 객체의 속성이 null이 아닐경우 다음을 진행한다.

25 : 타겟이 변환될 객체의 name속성을 비교하여 return 처리한다.

 

해결 간소화)

 


 

해결2. 함수화처리)

 

해결1은 단순히 조건문을 이용하여 리턴처리를 하였지만, 만약 main_mc안에 있는 close_mc객체가 많을경우엔?

 

일일이 조건문 처리를 해 줄 것이 아니라, 객체를 검색하여 조회처리를 하는 함수를 만들어서 재상용성과, 범용성을 보장 해야한다.

 

여기에서는 마우스아웃 되었을 때, checkInstance라는 함수를 실행시켜서 해당 상황을 검색한다.

 

즉, name속성이 아닌 전체 이벤트가 발생되는 객체인 e.currentTarget = main_mc와, e.relateObject를 파라메터값으로 받은뒤에

 

main_mc가 가지고있는 객체만큼 for~in 구문으로 조회한뒤 main_mc객체안에 포함된 객체이면 리턴값을 true로 처리한뒤

 

이 값을 가지고 마우스 아웃핸들러에서 조건처리를 한다.

 

해결 함수화.fla (파일첨부)


import flash.events.MouseEvent;
import caurina.transitions.Tweener;
import caurina.transitions.properties.ColorShortcuts;
ColorShortcuts.init();

main_mc.under_mc.buttonMode = true;
main_mc.under_mc.addEventListener(MouseEvent.MOUSE_OVER, overHan);
main_mc.under_mc.addEventListener(MouseEvent.MOUSE_OUT, underOutHan);

for(var i:int=0; i<4; ++i){
 var close_mc:MovieClip = main_mc["close_mc" + i] as MovieClip;
 close_mc.buttonMode = true;
 close_mc.addEventListener(MouseEvent.MOUSE_OVER, overHan);
 close_mc.addEventListener(MouseEvent.MOUSE_OUT, closeOutHan);
}

function overHan(e:MouseEvent):void{
 Tweener.addTween(e.target, {_color:"0x0066ff", time:1});
}

function underOutHan(e:MouseEvent):void{
 
 var container:MovieClip = e.currentTarget.parent as MovieClip; //main_mc
 var relate:Object = e.relatedObject;
 
 if(checkInstance(container,relate))return;
 else
 Tweener.addTween(e.target, {_color:null, time:1});
}

function closeOutHan(e:MouseEvent):void{
 Tweener.addTween(e.target, {_color:null, time:1});
}

function checkInstance($mc, $relate):Boolean{
 var MC:MovieClip = $mc;
 var relate:Object = $relate;
 var isBool:Boolean;
 
 for(var p:String in MC){
  if( MC[p] == relate ){
   isBool = true;
   break;
  }
 }
 return isBool;
}

 

10 : for문을 사용하여 close_mc0 ~ close_mc3 이렇게 4개의 객체 모두 동일한 이벤트 핸들러를 적용 시킨다.

26 : checkInstance 함수를 이용하여, 파라메터값으로 e.currentTarget(이벤트발생객체=main_mc)과 e.relateObject를 넘긴다.

      여기서 리턴값이 true이면 26번 라인에서 함수가 종료되고, false값이면 28번을 실행한다.

40 : for ~ in 구문으로 MC( = main_mc) 를 조회한후

41 : relate오브젝트가 포함되어있으면 true를 반환하고 함수를 종료한다.

46 : 객체조회를 한 후 해당사항이 없으면 false를 반환한다.

 

해결 함수화) 해결_함수화.fla

 

 

댓글