React, kakao 지도 띄우기 #5 여러개 인포윈도우띄우기(이벤트 등록하기)

noname·2020년 6월 27일
9
post-thumbnail

여러개 인포윈도우띄우기(이벤트 등록하기)

이번 포스팅에서는 여러개의 마커에 인포윈도우를 띄우고 동시에 이벤트를 등록하는 방법을 알아보겠습니다.
사실 카카오에서 하라는 대로만 하면 다 됩니다.
하지만 하라는대로가 제일 어렵죠....

완성코드

/*global kakao */
import React, { useEffect } from "react";
import { markerdata } from "../../data/markerData";

export default function Map() {
  useEffect(() => {
    mapscript();
  }, []);

  const mapscript = () => {
    let container = document.getElementById("map");
    let options = {
      center: new kakao.maps.LatLng(37.624915253753194, 127.15122688059974),
      level: 5,
    };

    //map
    const map = new kakao.maps.Map(container, options);
    markerdata.forEach((el) => {
      // 마커를 생성합니다
      const marker = new kakao.maps.Marker({
        //마커가 표시 될 지도
        map: map,
        //마커가 표시 될 위치
        position: new kakao.maps.LatLng(el.lat, el.lng),
      });
      // 마커에 표시할 인포윈도우를 생성합니다
      var infowindow = new kakao.maps.InfoWindow({
        content: el.title, // 인포윈도우에 표시할 내용
      });

      // 마커에 mouseover 이벤트와 mouseout 이벤트를 등록합니다
      // 이벤트 리스너로는 클로저를 만들어 등록합니다
      // 클로저를 만들어 주지 않으면 마지막 마커에만 이벤트가 등록됩니다
      kakao.maps.event.addListener(
        marker,
        "mouseover",
        makeOverListener(map, marker, infowindow)
      );
      kakao.maps.event.addListener(
        marker,
        "mouseout",
        makeOutListener(infowindow)
      );
    });
    // 인포윈도우를 표시하는 클로저를 만드는 함수입니다
    function makeOverListener(map, marker, infowindow) {
      return function () {
        infowindow.open(map, marker);
      };
    }

    // 인포윈도우를 닫는 클로저를 만드는 함수입니다
    function makeOutListener(infowindow) {
      return function () {
        infowindow.close();
      };
    }
  };

  return <div id="map" style={{ width: "100vw", height: "100vh" }}></div>;
}

인포윈도우 띄우기

forEach문 안에서 인포윈도우를 생성하는 생성자를 만들어줍니다.
여기서 저번 포스팅과 다르게 마커생성자를 변수에 담아줍니다.

카카오에서는 인포윈도우 content에 들어갈 부분이 div로 감싸진 채로 있지만, 저는 div로 감싸지않은 문자열을 넣었지만 작동이 잘되었습니다.

markerdata.forEach((el) => {
      // 마커를 생성합니다
      const marker = new kakao.maps.Marker({
        //마커가 표시 될 지도
        map: map,
        //마커가 표시 될 위치
        position: new kakao.maps.LatLng(el.lat, el.lng),
      });
      // 마커에 표시할 인포윈도우를 생성합니다
      var infowindow = new kakao.maps.InfoWindow({
        content: el.title, // 인포윈도우에 표시할 내용
      });

만약 마커없이 인포윈도우만 생성할거라면 마커처럼 인포윈도우를 작성하면 됩니다.

markerdata.forEach((el) => {
      // 인포윈도우를 생성합니다
      var infowindow = new kakao.maps.InfoWindow({
        //인포윈도우를 표시할 지도
        map: map,
        // 인포윈도우에 표시할 내용
        content: el.title, 
        //인포윈도우가 표시 될 위치
        position: new kakao.maps.LatLng(el.lat, el.lng),
      });

인포윈도우에 이벤트적용하기

카카오맵 API Docs에서 이벤트생성(적용) 메소드로 event.addListener를 사용합니다.

(혹시 캡쳐본을 사용하면 안되는 방침이있다면 알려주세요. 삭제하겠습니다.)

이벤트 제거 메소드로는 event.removeListener를 사용하지만 카카오에서 제공하는 샘플에서는 사용하지않았습니다.

forEach문 안에 이벤트리스너를 작성합니다.
카카오에서 이벤트리스너로는 클로저를 만들어 등록하지않으면 마지막 마커에만 이벤트가 등록된다고 합니다.

...
// 마커에 표시할 인포윈도우를 생성합니다
      var infowindow = new kakao.maps.InfoWindow({
        content: el.title, // 인포윈도우에 표시할 내용
      });

      //마커에 mouseover 이벤트와 mouseout 이벤트를 등록합니다
      //이벤트 리스너로는 클로저를 만들어 등록합니다
      //클로저를 만들어 주지 않으면 마지막 마커에만 이벤트가 등록됩니다
      kakao.maps.event.addListener(
        marker,
        "mouseover",
        makeOverListener(map, marker, infowindow)
      );
      kakao.maps.event.addListener(
        marker,
        "mouseout",
        makeOutListener(infowindow)
      );

인포윈도우를 표시하는 클로저만드는 함수

다른 더욱 좋은 방법이 있을지 모르겠지만, 저같은 주니어는 하라는 대로 하는 것이 제일 좋은 방법이라고 생각합니다.

이부분은 forEach문 안팎어디에 작성하든 실행됩니다. 저는 밖에서 작성했습니다.

   // 인포윈도우를 표시하는 클로저를 만드는 함수입니다
    function makeOverListener(map, marker, infowindow) {
      return function () {
        infowindow.open(map, marker);
      };
    }

    // 인포윈도우를 닫는 클로저를 만드는 함수입니다
    function makeOutListener(infowindow) {
      return function () {
        infowindow.close();
      };

결과물

인포윈도우가 생긴 것이 별로 안 예뻐서 저는 커스텀 오버레이를 사용하는 것을 추천합니다.
인포윈도우를 커스텀 하는 방법을 더 찾아보거나 그냥 커스텀 오버레이를 사용해야겠습니다.

다음 포스팅은 커스텀 오버레이 만들고 띄우는 것을 하려고합니다.
구직중이라 면접이 잡혀서 준비하느라 조금 늦게올릴 것 같아요.
만약 제가 너무너무너무 늦는다면 댓글 한번만 남겨주세요.
저번처럼 빠르게 달려오겠습니다!!

취업이 참 어렵습니다.. 하루하루 자존감이 떨어지고 뭘 더 해야하나 감이 안잡히고 불안하고 힘들지만, 힘냅시다.
저처럼 구직 중이신 주니어분들 꼭 좋은 회사, 잘 맞는 회사에 취직 되어서 고통스럽지만 행복한 코딩생활하시길 바랍니다!! 우리 모두 화이팅해요!

profile
notion으로 블로그이사를 하려다가 그냥 남아있습니다.

1개의 댓글

comment-user-thumbnail
2020년 7월 18일

덕담 감사합니다 우리 모두 화이팅! S2

답글 달기