[FAQ] 지도/로컬 API 문의 전 꼭 읽어 주세요.
안녕하세요.
가이드대로 script 안에서 mapContainer와 map 객체를 생성하는 방식으로 구현해봤는데요,
이렇게 script 생성과 동시에 지도를 생성하는 대신, 이 객체들을 한 함수에 넣어 원하는 시점에 지도를 생성할 수 있을까요?
실제로 해보니 하얀 빈 공간만 나타나서요…
[FAQ] 지도/로컬 API 문의 전 꼭 읽어 주세요.
안녕하세요.
가이드대로 script 안에서 mapContainer와 map 객체를 생성하는 방식으로 구현해봤는데요,
이렇게 script 생성과 동시에 지도를 생성하는 대신, 이 객체들을 한 함수에 넣어 원하는 시점에 지도를 생성할 수 있을까요?
실제로 해보니 하얀 빈 공간만 나타나서요…
이미 SDK가 로드되었다면 원하는 시점에 지도를 생성하시면 됩니다.
스크립트를 동적으로 로드하는 방법은 아래 문서와 같이 autoload=false 파라미터를 사용해서
kakao.maps.load 콜백 함수 안에서 지도를 생성해주세요.
https://apis.map.kakao.com/web/documentation/#load_load
그리고 지도를 생성했지만 하얀 화면만 보이는 경우는
지도가 표시될 요소의 스타일이 모달, 탭처럼 display: none에서 block으로 변경되는 경우 또는
width/height등 다른 스타일 속성이 동적으로 변경되는 경우에 발생합니다.
이 경우에 해당된다면 지도가 보이는 시점에 map.relayout();
API를 호출해주세요.
https://apis.map.kakao.com/web/documentation/#Map_relayout
답변 감사드립니다만, 제가 원하는 기능은 mapOption 속 disableDoubleClick과 draggable 값을 미리 정하고 그 후 그 값에 따라 터치 가능 여부가 결정되는 지도를 생성하는 것인데요, 가능할까요? 혹시 가능하다면 간단한 예제 코드도 부탁드려도 될까요? 자바스크립트를 처음 접해봐서… 미리 감사드립니다!
어떤 값에 따라 터치 가능 여부가 결정되는지 알 수 없지만, draggable, disableDoubleClick이 계속 변한다면
두 값을 변수로 관리하고 값이 변경될 때마다 두 변수값을 체크해서 원하는 조건에 맞을 때 지도를 생성하는 방법이 있고
지도 생성 조건이 단순하게 판단 가능하다면 변수 없이 조건을 확인해서 지도를 생성하는 방법도 있습니다.
아래는 터치가 가능한 디바이스인 경우 지도를 생성하는 코드입니다.
참고만 해주세요.
let map = null;
function isTouchDevice() {
return 'ontouchstart' in window || navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0;
}
function init() {
if(isTouchDevice()) { //true인 경우(터치가 되는 경우) 지도 표시
if(map) { //지도가 이미 생성된 경우면 return;
return;
}
let container = document.getElementById('map');
let options = {
center: new kakao.maps.LatLng(33.450701, 126.570667),
level: 3
//필요한 속성은 추가해주세요.
};
map = new kakao.maps.Map(container, options);
}
}
init();
자세하게 알려주셔서 감사합니다. 하지만 안드로이드 웹뷰로 스크립트를 부른 다음 예시로 주신 코드 속 init() 함수를 언제 호출해야하는지 잘 감이 오질 않습니다. 제 스크립트는 다음과 같습니다.
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript"
src="//dapi.kakao.com/v2/maps/sdk.js?appkey=f9fa76887058db0ceb622956fdea69f1&autoload=false"></script>
</head>
<body>
<div id="map" style="width:100%;height:100%;"></div>
<script type="text/javascript">
var content = '<div class ="label"><sv width="40px" height="40px" viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><title>PNG/settingsic_location</title><g id="PNG/settingsic_location" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"><g id="Common/location" transform="translate(9.499700, 6.500000)" fill="#4D4D52" fill-rule="nonzero"><path d="M10.5,15.0002579 C8.0145,15.0002579 6,12.9857579 6,10.5002579 C6,8.0147579 8.0145,6.0002579 10.5,6.0002579 C12.9855,6.0002579 15,8.0147579 15,10.5002579 C15,12.9857579 12.9855,15.0002579 10.5,15.0002579 M20.9475,9.4367579 C20.466,4.5557579 16.56,0.597257901 11.6835,0.0647579013 C5.355,-0.626742099 0,4.3112579 0,10.5002579 C0,12.5822579 0.609,14.5217579 1.6545,16.1537579 L8.664,26.0507579 C9.561,27.3167579 11.439,27.3167579 12.336,26.0507579 L19.3455,16.1537579 C20.568,14.2457579 21.192,11.9207579 20.9475,9.4367579" id="Fill-1"></path></g></g></svg></div>';
var customOverlay;
let timer = null;
const DELAY = 270; // 더블 클릭 감지 시간
function setGestureEnabled(isGestureEnabled) {
this.isGestureEnabled = isGestureEnabled;
}
function isTouchDevice() {
return 'ontouchstart' in window || navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0;
}
function init() {
if(isTouchDevice()) {
if(map) {
return;
}
let container = document.getElementById('map');
let options = {
center: new kakao.maps.LatLng(33.450701, 126.570667),
level: 5,
draggable: isGestureEnabled,
disableDoubleClick: !isGestureEnabled
};
map = new kakao.maps.Map(container, options);
}
}
function handleClick(event) {
if (timer === null) {
timer = setTimeout(() => {
timer = null;
singleClickHandler(event);
}, DELAY);
} else {
clearTimeout(timer);
timer = null;
doubleClickHandler(event);
}
}
function singleClickHandler(event) {
let latlng = event.latLng;
KakaoInterface.onClick(latlng.getLat(), latlng.getLng());
}
function doubleClickHandler(event) {
let latlng = event.latLng;
console.log(`double click! ${latlng.toString()}`);
}
function panTo(latitude, longitude) {
var moveLatLon = new kakao.maps.LatLng(latitude, longitude)
map.panTo(moveLatLon)
}
function drawPin(latitude, longitude) {
if (customOverlay != null) {
customOverlay.setMap(null);
}
position = new kakao.maps.LatLng(latitude, longitude);
customOverlay = new kakao.maps.CustomOverlay({
position: position,
content: content
});
customOverlay.setMap(map);
}
kakao.maps.event.addListener(map, 'click', handleClick);
kakao.maps.load(function() {
KakaoInterface.onMapReady();
});
</script>
</body>
</html>
init() 함수를 저 에서 호출해야 하는 건가요, 아님 스크립트가 로드된 다음 호출해야 할까요?
autoload=false 파라미터를 사용하신 경우 SDK가 로드된 이후 실행해야 하기 때문에
kakao.maps.load 콜백함수에서 실행하거나 SDK 로드 상태를 따로 관리한다면 상태가 변한 후 실행하시면 될 것 같습니다.
도움 주셔서 성공했습니다. 감사합니다!