본문 바로가기

Programming/etc

etc / javascript : daum.maps.event.addListener

여기서는. 반복문을 통해서!! 특히!!! marker 객체에 어떤 이벤트를 주려고 하는 경우에 주목합니다!!!

daum map api를 사용할때 어떤 이벤트를 등록할때 제목과 같은 메소드를 자주 사용하게 됩니다.
이 메소드는 인자로 (target(marker, map 등등), 이벤트 명("mouseover", 등등),  함수) 를 받고 있습니다.

1개의 특정 target 에 발생하는 이벤트를 작성할 경우에는 큰 문제가 발생하지 않습니다.
하지만...
반복문 등을 통해서 배열에 담겨있는 target 들을 리스너에 추가하려고 하면 error가 발생합니다.

보통 반복문에 접근할 경우에 작성하는 코드는
for(var i=0; i<tempArray.length; i++){
   daum.maps.event.addListener(tempArray[i], "mouseover", function(){
       // tempArray[i] 를 활용한 some logic
   });

을 작성하게 됩니다. 

전혀 문제될 것이 느껴지지 않아 이렇게 작성하지요..
그렇게 삽질은 시작되었던 것입니다 ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠ

대체 위 로직이 무엇이!!! 문제 이길래!!!!!!!!! 에러가 그렇게 하염없이 터질까요.

문제는 daum.maps.event.addListener 의 호출에 있지 않을까 조심스럽게 생각해봅니다.
눈이 팽그르르르 돌아가게 하는 daum느님의 코드를 쫓아가기엔
전 이제 덧셈뺄셈을 배우기 시작한 개발자니깐 패스하구요... 
조심스런 생각으로 추리를 하자면
tempArray[i]에는 특정 타겟이 있을 것이고
"mouseover"라는 네임은 그 타겟에 마우스가 올라가면 뭘 하겠다란 얘기입니다. 
그 뭘 하겠다라는 시점이 중요합니다.
정말 멍청한 저의 머리로 조심스레 추리해보자면(추리라... 전 개발자가 아닌가봅니다... OTL)
addListener에 등록한 target에 대한 event가 발생하였을 때에
function. 즉, some logic이 실행됩니다.
그런데 이때 some logic이 참조하는 것은 tempArray[i] 입니다.

코드상에는 문제가 전혀 없어보이지만 some logic의 tempArray[i] 는 무엇일까요?
addListener에 등록되는 function 내에 tempArray[i]는 알기 힘듭니다.
그 이유는 반복문 상에서 생각하고 있는 tempArray[i] 가 아닐 확률이 높기 때문이지요...
만약 위와 같이 작성하게 된다고 가정해볼게요.
tempArray = {"a", "b", "c"}
라는 것이 있다고 가정해봅시다.
그럼 tempArray[0]. 즉, daum.maps.event.addListener(a, "mouseover", function(){...});  이벤트가 추가됩니다.
그리고 이어서 tempArray[1] => b, tempArray[2] => c 타겟에 대한 이벤트도 추가되겠죠
자, 그리고 애플리케이션이 구동되고.... a이든 b이든 c이든 target에 event를 가합니다.
그럼 그때 실행되는 some logic의 tempArray는 무엇일까요? a? b? c??
황당하게도 tempArray[3], 즉 null 이든 뭐든 입니다.
반복문으로 어쨌거나 i는 3까지 수가 바뀌었고... 호출하는 시점은 그 시점이기 때문이지요.

이상 저의 위 로직에 대한 문제점에 대한 추리였습니다.

그럼 이걸 어떻게 해결할까요??
뭔가 tempArray[0]. 즉, a라는 객체가 고유한 객체이며
some logic은 a라는 객체만 바라볼 수 있도록 해야합니다.
반복문 내에서 고유한 네임의 변수를 생성하면서 addListener에 담으면 되겠다는 생각까지 가보았습니다.
그렇게 별의별 생각을 다해보았는데.... 

아예 function으로 해당 로직을 반복문에서 호출하게 되면
그 function의 인자는 고유한 인자로 리스너에 등록되는 객체이지 않을까란 생각을 해봤습니다. 
그래서...

for(var i=0; i<tempArray.length; i++){
   mapMarkerListener(tempArray[i]);
}
mapMarkerListener(targetMarker){
   daum.maps.event.addListener(tempArray[i], "mouseover", function(){
       // tempArray[i] 를 활용한 some logic
   });
}

이러한 로직으로 구현을 하였지요...
네, 잘 되더군요 -_-

정리하자면
daum.maps.event.addListener  이 메소드에 등록하는 function의 로직안에는
javascript가 로드되는 시점과 분리된, 실제 runtime 에서 발생하는 일들에 대한 정의만 해야하며.
또한 여러 target에 동일한 event를 가하고자 할때에는 array에 담긴 객체를 function 로직안에 넣지 말고
각 array에 담긴 객체를 어떻게든 유니크한 객체로 넣을 수 있도록 해야합니다.
말이 좀 어렵고 바로 위에 작성한 코드가 그것을 말하는 것인지 모르겠으나, 저렇게 하니까 유니크하게 보더군요.
(사실 저런 코드를 작성하게 된 가장 도움이 된 실험코드는 tempArray.pop(); 이었습니다.)