[JavaScript]Closing modal on outside click | 모달창 외부 클릭해서 닫게 하는 방법

이은진·2020년 11월 10일
12

JavaScript Study

목록 보기
12/24
post-custom-banner

포트폴리오 사이트나 기업 웹사이트를 만들 때, 모달(modal)창의 닫기 버튼 말고도 모달창을 제외한 화면을 클릭해서 닫을 수 있도록 해야 사용자가 불편함 없이 사이트를 이용할 수 있다. 간단한 HTML 태그 구성과 자바스크립트 단 몇 줄이면 해결 가능하다.

1. HTML, CSS 설정

큰 범위의 태그 두 개만 보면 된다. 가장 상위 태그로 <div class="modal-container" id="modal"></div>를, 바로 하위에 자식 태그로 <div class="modal"></div> 를 구성한다. 나중에 자바스크립트 이벤트를 받을 대상은 자식이 아닌 부모이므로 id값은 부모에만 지정해준다.


  <div class="modal-container" id="modal">
    <div class="modal">
      <button class="close-btn" id="close">
        <i class="fa fa-times"></i>
      </button>
      <div class="modal-header">
        <h3>Sign Up</h3>
      </div>
      <div class="modal-content">
        <p>Register with us to get offers, support and more</p>
        <form class="modal-form">
          <div>
            <label for="name">Name</label>
            <input type="text" id="name" placeholder="Enter Name" class="form-input">
          </div>
          <div>
            <label for="email">Email</label>
            <input type="email" id="email" placeholder="Enter email" class="form-input">
          </div>
          <div>
            <label for="password">Password</label>
            <input type="password" id="password" placeholder="Enter password" class="form-input">
          </div>
          <div>
            <label for="password2">Confirm Password</label>
            <input type="password" id="password2" placeholder="Confirm password" class="form-input">
          </div>

          <input type="submit" value="submit" class="submit-btn">
        </form>
      </div>
    </div>
  </div>

그리고 CSS에서 속성을 정의해준다. 부모 태그인 .modal-container 는 화면을 꽉 채운 어두운 사각형이고, 자식 태그인 .modal 은 모달창이다. 핵심은 .modal-container를 화면을 꽉 채운 상태로 만드는 것이다. 그래야 나중에 자식을 제외한 화면 아무 곳이나 클릭해도 모달창을 닫을 수 있다.

모달창은 기본적으로 보이지 않는 상태였다가 어떤 버튼을 누르는 등의 동작을 해야 보이기 때문에, display: none; 으로 설정해 두었다가 .show-modal 클래스가 추가되면 display: block; 으로 바뀌게 한다.

.modal-container {
  background: rgba(0,0,0,.5);
  display: none;
  /* this is how we cover the entire page */
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
}

.modal-container.show-modal {
  display: block;
}

.modal {
  background: white;
  border-radius: 5px;
  box-shadow: 0 0 10px rgba(0,0,0,.3);
  position: absolute;
  overflow: hidden;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  max-width: 100%;
  width: 400px;

  animation-name: modalopen;
  animation-duration: var(--modal-duration);
}

2. Javascript 이벤트리스너 추가

자바스크립트로 addEventListener를 추가하는 대상은 전체 화면을 차지하고 있는 부모 태그인 modal-container다. document.getElementById('modal')로 부모 태그를 선택해, 버튼을 클릭하면 클래스에 show-modal가 추가되도록 한다.

const modal = document.getElementById('modal')

//Show modal
open.addEventListener('click', () => {
  modal.classList.add('show-modal')
})

//Hide modal
close.addEventListener('click', () => {
  modal.classList.remove('show-modal')
})

그리고 다음은 이 글의 핵심이 되는 두 줄이다. window에 이벤트리스너를 추가해, 클릭한 대상이 부모 태그인 경우 .show-modal 클래스를 제거하도록 하면 된다. 자식 태그는 위의 css 속성에서 position: absolute;로 설정되었기 때문에 자식 태그 영역 내에서는 x 버튼을 클릭하지 않으면 닫히지 않는다. 클릭한 타겟이 자식 태그 영역 밖이면서 부모 태그 영역 안이기 때문에 모달창은 꺼지게 된다.

//Hide modal
window.addEventListener('click', (e) => {
  e.target === modal ? modal.classList.remove('show-modal') : false
})
profile
빵굽는 프론트엔드 개발자
post-custom-banner

2개의 댓글

comment-user-thumbnail
2020년 12월 6일

감사합니다 !

답글 달기
comment-user-thumbnail
2020년 12월 15일

Thanks a lot for sharing!JOKER123

답글 달기