본문 바로가기
공부/naver map api

[naver map api] 버튼 이벤트, 모달창 생성

by 고기 2022. 1. 27.

이전 글에서 이미지, 버튼, 텍스트박스 등을 만드는 법에 대해 알아보았다. 이번 글에서는 버튼을 클릭했을 때 발생할 이벤트 함수를 작성하는 방법에 대해 알아본다.

 

버튼을 클릭했을 때 발생하는 이벤트는 크게 세가지가 있다. 첫번째는 버튼을 클릭했을 때, 해당 위치로 이동하면서 레이어를 추가로 그려주는 이벤트이고 두번째는 버튼을 클릭했을 때 모달 창을 출력해주는 이벤트이며, 세번째는 버튼을 클릭했을 때 주소가 입력된 텍스트박스의 값이 있으면 해당 주소로 이동하는 이벤트이다.

사진1

 

리모콘 중단의 검색 버튼과 하단의 행정동 버튼들에 대한 이벤트를 작성한다. 어차피 비슷한 기능들이다.

사진2

 

우선 모달 창을 출력하는 버튼 이벤트부터 작성한다. 

/* 요구사항 팝업 이벤트 */
window.onload = function() {
    function onClick() {
        document.querySelector('.modal_wrap').style.display ='block';
        document.querySelector('.black_bg').style.display ='block';
    }   
    function offClick() {
        document.querySelector('.modal_wrap').style.display ='none';
        document.querySelector('.black_bg').style.display ='none';
    }
 
    document.getElementById('info').addEventListener('click', onClick);
    document.querySelector('.modal_close').addEventListener('click', offClick); 
};

 

요구사항 버튼을 클릭하면 출력되는 모달 창이다. 요구사항 버튼을 클릭하면 onclick() 함수가 실행되어 모달 창이 생성되고, 오른쪽 상단의 x를 클릭하면 offclick() 함수가 실행되어 모달 창이 종료된다. 출력할 내용은 이미지나 텍스트 등으로 입력하면 되는데, 이전 글에서 모달 창을 생성하는 html code를 같이 참고해서 작성하면 된다.

사진3

 

다음으로 행정동 이동 버튼 이벤트를 작성한다. 

/* 해당 태그를 가지고 있는 버튼이 눌리면 clickButton() 함수를 호출 */
document.getElementById("et").onclick  = function (e) { clickButton(행정동좌표[0],   행정동줌[0],  행정동주소[0],   행정동마커[0],   행정동통개수[0] , e, "et"); } // 도산동
document.getElementById("er").onclick  = function (e) { clickButton(행정동좌표[1],   행정동줌[1],  행정동주소[1],   행정동마커[1],   행정동통개수[1] , e, "er"); } // 동곡동
document.getElementById("qf").onclick  = function (e) { clickButton(행정동좌표[2],   행정동줌[2],  행정동주소[2],   행정동마커[2],   행정동통개수[2] , e, "qf"); } // 본량동
document.getElementById("qd").onclick  = function (e) { clickButton(행정동좌표[3],   행정동줌[3],  행정동주소[3],   행정동마커[3],   행정동통개수[3] , e, "qd"); } // 비아동
document.getElementById("te").onclick  = function (e) { clickButton(행정동좌표[4],   행정동줌[4],  행정동주소[4],   행정동마커[4],   행정동통개수[4] , e, "te"); } // 삼도동
document.getElementById("tw1").onclick = function (e) { clickButton(행정동좌표[5],   행정동줌[5],  행정동주소[5],   행정동마커[5],   행정동통개수[5] , e, "tw1"); } // 송정1동
document.getElementById("tw2").onclick = function (e) { clickButton(행정동좌표[6],   행정동줌[6],  행정동주소[6],   행정동마커[6],   행정동통개수[6] , e, "tw2"); } // 송정2동
document.getElementById("td").onclick  = function (e) { clickButton(행정동좌표[7],   행정동줌[7],  행정동주소[7],   행정동마커[7],   행정동통개수[7] , e, "td"); } // 수완동
document.getElementById("tr").onclick  = function (e) { clickButton(행정동좌표[8],   행정동줌[8],  행정동주소[8],   행정동마커[8],   행정동통개수[8] , e, "tr"); } // 신가동
document.getElementById("tc").onclick  = function (e) { clickButton(행정동좌표[9],   행정동줌[9],  행정동주소[9],   행정동마커[9],   행정동통개수[9] , e, "tc"); } // 신창동
document.getElementById("tg").onclick  = function (e) { clickButton(행정동좌표[10],  행정동줌[10], 행정동주소[10],  행정동마커[10],  행정동통개수[10], e, "tg"); } // 신흥동
document.getElementById("df").onclick  = function (e) { clickButton(행정동좌표[11],  행정동줌[11], 행정동주소[11],  행정동마커[11],  행정동통개수[11], e, "df"); } // 어룡동
document.getElementById("dt").onclick  = function (e) { clickButton(행정동좌표[12],  행정동줌[12], 행정동주소[12],  행정동마커[12],  행정동통개수[12], e, "dt"); } // 우산동
document.getElementById("ds").onclick  = function (e) { clickButton(행정동좌표[13],  행정동줌[13], 행정동주소[13],  행정동마커[13],  행정동통개수[13], e, "ds"); } // 운남동
document.getElementById("dr1").onclick = function (e) { clickButton(행정동좌표[14],  행정동줌[14], 행정동주소[14],  행정동마커[14],  행정동통개수[14], e, "dr1"); } // 월곡1동
document.getElementById("dr2").onclick = function (e) { clickButton(행정동좌표[15],  행정동줌[15], 행정동주소[15],  행정동마커[15],  행정동통개수[15], e, "dr2"); } // 월곡2동
document.getElementById("dr").onclick  = function (e) { clickButton(행정동좌표[16],  행정동줌[16], 행정동주소[16],  행정동마커[16],  행정동통개수[16], e, "dr"); } // 임곡동
document.getElementById("ce1").onclick = function (e) { clickButton(행정동좌표[17],  행정동줌[17], 행정동주소[17],  행정동마커[17],  행정동통개수[17], e, "ce1"); } // 첨단1동
document.getElementById("ce2").onclick = function (e) { clickButton(행정동좌표[18],  행정동줌[18], 행정동주소[18],  행정동마커[18],  행정동통개수[18], e, "ce2"); } // 첨단2동
document.getElementById("ve").onclick  = function (e) { clickButton(행정동좌표[19],  행정동줌[19], 행정동주소[19],  행정동마커[19],  행정동통개수[19], e, "ve"); } // 평동
document.getElementById("gs").onclick  = function (e) { clickButton(행정동좌표[20],  행정동줌[20], 행정동주소[20],  행정동마커[20],  행정동통개수[20], e, "gs"); } // 하남동]

 

행정동 이동 버튼이 클릭되면 clickButton() 함수를 실행시킨다. 실행된 clickButton() 함수에 대한 설명은 주석을 참고하면 된다.

/*
**********************************************************************
clickButton(point, zoom, address1, address2, number, e, name)
행정동 버튼 클릭 시 해당 행정동으로 이동하면서 통경계를 그림

작성순서
1) btncolor(e);
   클릭한 버튼 색 바꿈
2) deletexJson(tmp[0], tmp[1], tmp[2], tmp[3]);
   이전에 생성했던 통 경계를 지움
3) mapMove(좌표, 줌 레벨)
   클릭한 행정동 위치로 맵 시점을 이동
4) readxJson(행정동 통 파일 경로, 확장자, 통 개수);
   클릭한 행정동의 통 경계를 그림
5) map.data.addGeoJson(overrideStyle(icon : 마커 이미지 경로))
   행정동 마커를 그림
6) tmp
   deletexJson에서 사용할 임시 변수
   tmp[0] : 이전 행정동 통 파일 경로
   tmp[1] : 파일 확장자
   tmp[2] : 이전 행정동 마커 파일 경로
   tmp[3] : 이전 행정동 통 개수
7) makebtn(name);
   클릭한 행정동 통 개수만큼 버튼 생성
**********************************************************************
*/
function clickButton(point, zoom, address1, address2, number, e, name){
    btncolor(e),
    deletexJson(tmp[0], tmp[1], tmp[2], tmp[3]);
    mapMove(point, zoom); 
    readxJson(address1, '.geojson', number);
    
    fetch(address2)
    .then(response => response.json())
    .then(json => map.data.addGeoJson(json))
    .then(
        feature =>
        feature.forEach(function(e){
            map.data.overrideStyle(e, {
                icon: './행정동/marker/'+e['property_tong']+'.png'
            });
            setTimeout(() => {}, 1000);
        })        
    );    
    
   tmp=[];
   tmp.push(address1, '.geojson', address2, number);  
   makebtn(name);
}

 

우선 clickButton() 함수에서 첫번째로 실행되는 btncolor() 함수는 행정동 버튼을 클릭하면 행정동 버튼 색이 변하게 한다. 

/*
**********************************************************************
function btncolor(btn)
행정동 버튼 클릭 시 클릭한 행정동 버튼 색을 바꿈
**********************************************************************
*/
function btncolor(btn){
    if (btncolortmp[0] !== undefined){
        document.getElementById(btncolortmp[0]).style.background="lightblue";
    }

    btncolortmp = [];
    btncolortmp.push(btn.path['0'].id);    
    document.getElementById(btncolortmp[0]).style.background="orange";
}

 

두 번째로 실행되는 deletexJson()는 이미 그려져 있던 행정동 경계가 있다면 지운다.

/*
**********************************************************************
deletexJson(urlpre, urlsuf, url2, number)
인수로 받은 파일 경로에 존재하는 json파일의 통 경계를 삭제

기능설명
map.data.removeGeoJson(Json file) -> 해당 Json file의 폴리곤 좌표를 지도에서 제거

참고 url : https://navermaps.github.io/maps.js.ncp/docs/naver.maps.Data.html
**********************************************************************
*/
function deletexJson(urlpre, urlsuf, url2, number){
    if (urlpre !== undefined){
        let url1 = [];

        for (let i = 0; i < number; i++) {        
            if (String(i+1).length === 1) {            
                url1[i] = urlpre + '0' + String(i+1) + urlsuf;
            }
            else {
                url1[i] = urlpre + String(i+1) + urlsuf;
            }
        }
            
        url1.forEach(e=>  
            fetch(e)        
            .then(response => response.json())
            .then(json => map.data.removeGeoJson(json))        
        )
        
        fetch(url2)
        .then(response => response.json())
        .then(json => map.data.removeGeoJson(json))               
    }
}

 

세 번째로 실행되는 mapMove() 함수는 클릭한 행정동 좌표로 이동한다.

/* 
**********************************************************************
mapMove(point, address)
해당 행정동으로 이동함

작성순서
1) map.morph(좌표, 줌level) 
   지정한 좌표로 이동해서 지정한 레벨만큼 줌 시킴
**********************************************************************
*/
function mapMove(point, zoom){  
    map.morph(point, zoom);
}

 

네 번째로 실행되는 readxJson() 함수는 클릭한 행정동 통 경계를 그린다.

/*
**********************************************************************
readxJson(urlpre, urlsuf, number)
각 행정동 통 경계 파일 가져오는 함수 -> 인수로 받은 파일 경로에 json파일이 존재하면 
                                     해당 행정동 경계를 그림
기능설명
map.data.addGeoJson(Json file) -> 해당 Json file의 폴리곤 좌표를 지도에 출력
                                  json file 내용 확인 예시
                                  console.log("행정동test", Json['features'][0]['properties']);                            

참고 url : https://navermaps.github.io/maps.js.ncp/docs/naver.maps.Data.html
**********************************************************************
*/
function readxJson(urlpre, urlsuf, number){
    let url = [];    

    for (let i = 0; i < number; i++) {        
        if (String(i+1).length === 1) {            
            url[i] = urlpre + '0' + String(i+1) + urlsuf;
        }
        else {
            url[i] = urlpre + String(i+1) + urlsuf;
        }
    }        

    url.forEach(e=>  
        fetch(e)        
        .then(response => response.json())
        .then(json => map.data.addGeoJson(json))      
    )     
}

 

함수는 아니지만 다섯째로 실행되는 이 코드는 클릭한 행정동의 통 별 마커를 설정한다. 마커들은 이미지 파일로 불러오게 했다.

    fetch(address2)
    .then(response => response.json())
    .then(json => map.data.addGeoJson(json))
    .then(
        feature =>
        feature.forEach(function(e){
            map.data.overrideStyle(e, {
                icon: './행정동/marker/'+e['property_tong']+'.png'
            });
            setTimeout(() => {}, 1000);
        })        
    );    
    
   tmp=[];
   tmp.push(address1, '.geojson', address2, number);

 

마지막으로 실행되는 makebtn() 함수는 클릭된 행정동의 통 개수만큼 버튼을 생성하고 생성된 버튼에 클릭 이벤트를 부여한다.

/*
**********************************************************************
function makebtn(s)
행정동 버튼 클릭 시 행정동 통 개수만큼 버튼 생성
**********************************************************************
*/
function makebtn(s){    
    let layer = map.data.getAllFeature();
    console.log("--->", s, tmp[3], layer);
    
    $(".tongbtn").detach();
    
    for (let tongname=1; tongname<tmp[3]; tongname++){
        $(".gwd").append("<button class='tongbtn' id='"+tongname+"'>"+tongname+"</button>")
    }
    
    $(".tongbtn").on("click", function(e) {
        let id = e.target.id

        if (s==='et'){                        
            if ((id === '16') | (id === '17')) {
                id="16, 17";
            }
        }        
        
        for (let x=22; x<22+tmp[3]; x++){            
            if (id === layer[x]['property_tong']){
                console.log("-->>>", x, layer[x], layer[x]['property_tong'], "통");               

                if (layer[x].getProperty('focus') !== true) {
                    for (let y=22; y<22+tmp[3]; y++){
                        if (layer[y]['property_focus'] === true){
                            layer[y].setProperty('focus', false);
                        }
                    }
                }

                layer[x].setProperty('focus', true);
            }
        }
    })
}

 

작성한 기능을 웹페이지에서 실행시키면 다음과 같다.

사진4

 

사진5

 

여기까지 버튼 이벤트 작성에 대해 알아보았다. 주소 검색하는 방법까지 쓰려면 글이 너무 길어질 것 같아서 다음 글에서 주소를 검색하는 방법에 대해 작성한다.

 

댓글