7/4 개발일기
홈페이지를 개발하던 중, 가장 간단할 거라고 예상했던 회사 소개 페이지에서 막혔다. 문제는 다음지도 API 를 사용하여 약도를 구현하는데, 지도가 제대로 뜨지 않았다. 이 페이지는 Tab bar로 구현되어 있어 요소들의display 속성에 none, block 을 번갈아 주는데 찾아보니 이 때문에 일어난 일이었다. 요약하면 아래와 같다
-문제현상 : Tab 타입으로 지도를 여러개 구현할 경우 지도가 제대로 로드되지 않음.
-문제원인 : map을 생성할 때 currentStyle을 갖고 오는데, display 속성의 경우 해당 요소의 width/height 값을 삭제함. 이 때문에 map이 제대로 생성되지 않으면서 발생한 문제임.
-문제해결 : 요소의 width, height 를 보장하면서 가시성 여부만 바꿔주는 visibility 로 지도 div를 제어한다. 겸사겸사 동적으로, 최대한 소스는 깔끔하게 해보자.
이번에 알았는데 .append() 를 사용해 div를 생성할 경우, 해당 function 이 끝나지 않는한 javascript에서는 그 div를 제대로 생성된 것으로 여기지 않는다. 처음에는 .append() 로 map을 동적 생성해주려 했으나 잘 되지 않았던 이유였다.
예컨대 아래처럼 append 를 하고 출력하면,
parentDiv.append("<div id='child' class='map' style='height:400px;'></div>");
각각 값이 다르게 나온다. jQuery 는 append 된 div의 스타일을 정확히 인식하는 반면
plain javascript 는 그렇지 않았다.
console.log($('#child').css("height")); // 400px
console.log(document.getElementById('child').clientHeight); //0
console.log(document.getElementById('child').style.height); //undefined
나는 bootstrap에서 제공하는 tab 스타일을 썼다.
이 경우 다음지도 API 다중 맵을 동적 생성하는 소스는 아래와 같다.
$("[role='tab']").click(function(){
//다른 지도들은 hidden 처리한다
$('.map').css("visibility","hidden");
//target이 되는 탭 패널 div와 지도를 선택한다
var target = $(this).attr("aria-controls");
var targetMap = $(this).attr("aria-controls") + "-map";
//target이 되는 지도만 visible 처리한다.
$("#"+targetMap).css("visibility","visible");
//지도에 param 속성으로 부여되어 있는 위도, 경도 값을 갖고 온다
var lat = $("#"+targetMap).attr("param").split(":")[0];
var lng = $("#"+targetMap).attr("param").split(":")[1];
mapContainer = document.getElementById(targetMap),
mapOption = {
center: new daum.maps.LatLng(lat, lng),
level: 3
};
var map = new daum.maps.Map(mapContainer, mapOption);
map.relayout(); //지도 레이아웃을 재로딩한다
});
})
내 경우 탭 패널 div의 ID와 지도가 들어갈 영역의 div ID를 비슷하게 맞추었다.
tab 패널 div ID가 kangbuk 인 경우 map의 ID는 kangbuk-map 이다.
HTML 소스는 아래와 같다(bootstrap tab 스타일)
bootstrap 기반 tab nav html
<li role="presentation">
<a href="#kangbuk" aria-controls="kangbuk" role="tab" data-toggle="tab">
강북지점
</a>
</li>
tab 패널 div
<div role="tabpanel" class="tab-pane active" id="kangbuk">
지도 div (tab-content 바깥에 둔다)
<div id="kangbuk-map" class="map" param="37.00000:126.00000"></div>
여기서 param은 내가 위도와 경도 값을 관리하기 위해 별도로 준 속성값이다. 이렇게 하면 위도와 경도를 다른 변수로 관리해야 할 필요도 없고 수정도 쉬워 코드가 한결 깔끔해진다.