다중 마커 및 오버레이 닫기 관련 문제

안녕하세요 마커에 오버레이 띄우는 작업 중 오버레이 닫기 오류 관련하여 질문 드립니다.

                var markers = []; // 지도에 표시된 마커 객체를 가지고 있을 배열입니다
				var contents = [];
				var overlays = [];
				var mapContainer = document.getElementById('map'), // 지도를 표시할 div  
				mapOption = {
					center : new kakao.maps.LatLng(37.5397629769285, 126.996240829219), // 지도의 중심좌표
					level : 5
				// 지도의 확대 레벨
				};

				var map = new kakao.maps.Map(mapContainer, mapOption); // 지도를 생성합니다

				// 마커를 표시할 위치와 title 객체 배열입니다
				var positions = [
						<%
							ArrayList<ContentDTO> list = (ArrayList<ContentDTO>)request.getAttribute("list");
						
							for(int i = 0; i < list.size(); i++) {
							if(i == list.size()-1) {
						%>
							{
								title : '<%=list.get(i).getName()%>',
								address : '<%=list.get(i).getAddress()%>',
								category : '<%=list.get(i).getCategory()%>',
								latlng : new kakao.maps.LatLng<%=list.get(i).getCoordinate()%>
							}
							
						<%
							} else {
						%>
							{
								title : '<%=list.get(i).getName()%>',
								address : '<%=list.get(i).getAddress()%>',
								category : '<%=list.get(i).getCategory()%>',
								latlng : new kakao.maps.LatLng<%=list.get(i).getCoordinate()%>
							},
						<%
							}
							}
						%>
				];
				    
				for (var i = 0; i < positions.length; i ++) {
					// 마커 이미지의 이미지 주소입니다
					if(positions[i].category == '관광지') var imageSrc = "https://t1.daumcdn.net/localimg/localimages/07/mapapidoc/markerStar.png";
					else if(positions[i].category == '숙박시설') var imageSrc = "https://t1.daumcdn.net/localimg/localimages/07/mapapidoc/markerStar.png";
					else var imageSrc = "https://t1.daumcdn.net/localimg/localimages/07/mapapidoc/markerStar.png";
					
				    // 마커 이미지의 이미지 크기 입니다
				    var imageSize = new kakao.maps.Size(24, 35); 
				    
				    // 마커 이미지를 생성합니다    
				    var markerImage = new kakao.maps.MarkerImage(imageSrc, imageSize); 
				    
				    // 마커를 생성합니다
				    var marker = new kakao.maps.Marker({
				        map: map, // 마커를 표시할 지도
				        position: positions[i].latlng, // 마커를 표시할 위치
				        title : positions[i].title, // 마커의 타이틀, 마커에 마우스를 올리면 타이틀이 표시됩니다
				        image : markerImage, // 마커 이미지 
				        clickable: true // 마커를 클릭했을 때 지도의 클릭 이벤트가 발생하지 않도록 설정합니다
				    });
				    markers.push(marker);
				}
				
				for(var i=0; i<positions.length; i++) {
		         	// 마커 위에 커스텀오버레이를 표시합니다
			        // 마커를 중심으로 커스텀 오버레이를 표시하기위해 CSS를 이용해 위치를 설정했습니다
					var overlay = new kakao.maps.CustomOverlay({
		            	map: map,
		            	position: markers[i].getPosition()
		         	});
					overlay.setMap(null);
					
					var content = '<div class="wrap">' + 
		            '    		   <div class="info">' + 
		            '        	   <div class="title">' + positions[i].title + 
		            '              <div class="close" onclick="closeOverlay()" title="닫기"></div>' + 
		            '        	   </div>' + 
		            '        	   <div class="body">' + 
		            '              <div class="img">' +
		            '              <img src="image/contents/hyattseoul1.PNG" width="73" height="70">' +
		            '              </div>' + 
		            '              <div class="desc">' + 
		            '              <div class="ellipsis">' + positions[i].address + '</div>' + 
		            '              </div>' + 
		            '              </div>' + 
		            '    		   </div>' +    
		            '			   </div>';
		            
		            overlay.setContent(content);
					
					// 마커를 클릭했을 때 커스텀 오버레이를 표시합니다
					kakao.maps.event.addListener(markers[i], 'click', function(o) {
						return function() {
							o.setMap(map);
						}
				    }(overlay));
				}
				
				function closeOverlay() {
			        overlay.setMap(null);
			    }
				
				// 배열에 추가된 마커들을 지도에 표시하거나 삭제하는 함수입니다
				function setMarkers(map) {
				    for (var i = 0; i < markers.length; i++) {
				        markers[i].setMap(map);
				    }
				}

				// "마커 보이기" 버튼을 클릭하면 호출되어 배열에 추가된 마커를 지도에 표시하는 함수입니다
				function showMarkers() {
				    setMarkers(map);
				}

				// "마커 감추기" 버튼을 클릭하면 호출되어 배열에 추가된 마커를 지도에서 삭제하는 함수입니다
				function hideMarkers() {
				    setMarkers(null);    
				}

오버레이를 생성하고 content를 추가하는 식으로 코딩을 했는데요
마커 클릭시 해당하는 오버레이가 정상적으로 출력되긴합니다.
다만, 닫기 버튼 클릭시 마지막 오버레이만 닫힙니다.
닫기 버튼에서 closeOverlay() 함수가 있는데 각 마커 클릭시 열리는 오버레이를 closeOverlay() 함수의 파라미터로 넘겨줘야 할거같은데 도무지 방법을 모르겠습니다.
자바스크립트 부분이 약해서 그런지 감이 오질 않네요
고수님들의 답변 부탁드리겠습니다.
(positions 배열에 요소 추가하는 부분에 스크립트릿이 들어가는 부분은 제가 스크립트에서 jstl 사용 방식이 조금 서툴러서 급한대로 스크립트릿을 사용한 점 양해 부탁드립니다ㅜㅜ)

1개의 좋아요

아래 링크와 같이 컨텐츠는 HTMLElement로 생성하여 이벤트를 등록해주시고
스코프 유지를 위해 forEach 또는 함수 스코프로 만들어주세요.


마커를 생성하는 반복문 안에서 모두 처리가 가능합니다.
첫 번째 반복문에 마커 생성, 커스텀 오버레이 생성 및 닫기 이벤트 추가, 마커 이벤트를 등록해주세요.
그리고 커스텀 오버레이 생성 시 map 파라미터를 부여하지 않으면 지도에 올라가지 않기 때문에
위 로직처럼 map 파라미터를 적용하고 setMap(null);을 호출하지 않아도 됩니다.

정리하면 아래와 같은 로직으로 구현이 됩니다.
참고해주세요.

positions.forEach(function (pos) {
    // 마커를 생성합니다
    var marker = new kakao.maps.Marker({/* do something */});

    // content HTMLElement 생성
    var content = document.createElement('div');

    var info = document.createElement('span');
    info.appendChild(document.createTextNode(pos.title));
    content.appendChild(info);

    var closeBtn = document.createElement('button');
    closeBtn.appendChild(document.createTextNode('닫기'));
    // 닫기 이벤트 추가
    closeBtn.onclick = function() {
        overlay.setMap(null);
    };

    content.appendChild(closeBtn);

    // customoverlay 생성, 이때 map을 선언하지 않으면 지도위에 올라가지 않습니다.
    var overlay = new daum.maps.CustomOverlay({
        position: pos.latlng,
        content: content
    });

    // 마커를 클릭했을 때 커스텀 오버레이를 표시합니다
    kakao.maps.event.addListener(marker, 'click', function() {
        overlay.setMap(map);
    });
});
2개의 좋아요
마커, 오버레이 이용시 마커 click 이벤트 등록에 따른 오버레이 제어 방법
카카오 지도 api 다중 오버레이 질문
React로 customOverlay 만든후 onclick 이벤트넣기
For문과 addEventListener 혼용 사용 관련 문제
마커에 오버레이로 이벤트 발생
안녕하세요 카카오맵 마커에 대한 질문입니다
다중마커 다중오버레이 질문입니다
여러 마커에 각각의 인포인도우를 설정하고 싶습니다
카카오맵API 여러개마커에 각자다른 커스텀오버레이
닫기가 가능한 커스텀 오버레이 API 사용관련 문의
지도 overlay 이벤트 처리시 각각의 overlay에 접근하려면 어떻게해야 하나요?
지도 overlay 이벤트 처리시 각각의 overlay에 접근하려면 어떻게해야 하나요?
안녕하세요 다중마커로 닫기가 가능한 커스텀 오버레이를 구현하려고 하는데 커스텀 오버레이는 나타나는데 하나만 지워지고 나머지는 그냥 그대로 있습니다
Api 지도를 통한 매장찾기 기능
커스텀 오버레이 닫기 버튼 appendChild()
카카오맵 api 다양한이미지 마커 표시하기에 커스텀 오버레이 클릭이벤트 기능 구현
Infowindow 또는 customoverlay 에 addListener 은 안되나요?
커스텀 오버레이에서 닫기 버튼이 안눌립니다
커스텀 오버레이 마커 클릭시 open
커스텀오버레이 관련
클러스터마커에 커스텀오버레이 생성 문의
커스텀 오버레이 질문
모바일에서 오버레이 내부의 스크롤

정말 감사합니다.
덕분에 createElement 배워갑니다.
해결했습니다. 오전에 글을 보고 지금 해결 후 바로 답글 다네요ㅜㅜ
감사합니다.

3개의 좋아요