모달을 만들다보면, 모달 외부를 클릭했을 떄 모달이 닫히도록 만들고 싶어지는 때가 생긴다.
이를 구현하기 위한 여러방법이 있지만 그 중 closest()
를 활용한 방법을 정리해본다.
공식적인 정의는 아래와 같다
기준 Element 에서부터 closest() 메소드를 통해 자신부터 부모 요소 단위로 출발하여 각 요소가 지정한 선택자에 만족할 때까지 탐색한다(문서 루트까지 이동). 이 중 가장 가깝게 조건에 만족한 부모 요소가 반환되며, 조건에 만족한 요소가 없으면 null 값을 반환한다.
좀 더 이해하기 쉽게 풀어 설명하면,
closest()메소드에다 특정 인자(보통 class 또는 id값)를 입력하면, 이벤트가 발생한 위치를 시작으로 해당 인자를 포함하고 있는 부모 요소로 점진적으로 탐색을 하며 해당 인자를 포함한 최대 영역을 찾아내는 반환하는 것이다.
이벤트가 발생한 위치에서 root파일까지 탐색하는 동안 해당 인자를 못찾아내는 경우 null
값을 반환한다.
import React, { useEffect, useState } from 'react';
import styled from 'styled-components';
const Modal = ({ coinData, setModalOn }) => {
const handleWindow = e => {
const clicked = e.target.closest('.modal');
if (clicked === null) {
setModalOn(prev => !prev);
}
};
return (
<Container onClick={handleWindow}>
<ModalContainer className="modal">
<H1>Coin Details</H1>
<Dl>
<Dt>Coin Name</Dt>
<Dd>{name}</Dd>
<Dt>PassWord</Dt>
<Dd>{info?.find(el => el.coin_name === name).password}</Dd>
<Dt>Balance</Dt>
<Dd>{info?.find(el => el.coin_name === name).num}</Dd>
</Dl>
</ModalContainer>
</Container>
);
};
위의 예시의 handleWindow
를 분석해보면, 변수clicked
는 이벤트가 발생한 곳으로부터 modal
이라는 클래스명을 포함하고 있는 부모요소를 탐색한다.
부모 요소 중 modal
클래스가 포함되어있다면 -> 해당 html을 반환할 것이며,
modal
클래스가 포함되어 있지 않은 경우 -> null
을 반환한다.
우리는 modal
클래스의 바깥 부분을 클릭했을 때 해당 모달이 사라지길 원하기 때문에, clicked
의 값이 null
인 경우를 탐색해서 null
인 경우 모달이 닫히도록 작업해주어야 한다. (그렇기에 setState를 활용하여 modal state를 변경해주도록 하였다)
console창에다가 e.target.closest(".modal")
을 찍어보면, 모달을 클릭할때는 modal class가 포함된 html이 반환되는 것을, 모달 외부를 클릭하면 null
이 반환되는 것을 확인 가능하다.
이에 맞추어 closest()
메소드의 결과값이 null일때만 모달이 꺼지도록 잘 구현된 모습을 볼 수 있다.