javascript를 통해서 가장 가까운 요소를 찾는 방법 중에 closest()라는 메서드가 있습니다.
DOM 노드의 부모를 찾는데 어려움을 겪은 적이 있나요?
<div data-id="normal">
<button>Click</button>
</div>
data-id 값을 한번 가져와볼까요?
const button = document.querySelector("button");
button.addEventListener("click", (event) => {
console.log(event.target.parentNode.dataset.id);
// normal
});
이런 케이스의 경우에는 parentNode API로도 충분합니다.
하지만 HTML 구조가 조금 더 중첩이 되면 어떨까요?
반복문으로 parentNode를 계속 돌면서 찾는 것은 매우 비효율적일 수도 있습니다.
물론 closest()가 적용이 안되는 환경에서는 while문과 같은 반복문을 사용해야합니다.
function getParentNode(el, tagName) {
while (el && el.parentNode) {
el = el.parentNode;
if (el && el.tagName == tagName.toUpperCase()) {
return el;
}
}
return null;
}
위 내용을 보시면 계속해서 el 자체가 존재한다면 el에 다시 그 부모를 할당하는 식으로 반복해서 해당 태그를 리턴해주는 함수입니다.
console.log(getParentNode(button, 'div').dataset.id);
같은 상황에서 div태그 내에 많은 HTML 구조가 포함되고 있을 때 위와 같이 사용하시면 됩니다.
하지만 div태그가 반복된다면 어떨까요? 완벽하지 않네요.
하위 브라우저 호환성까지 포함되는 jquery에서는 다음과 같이 사용할 수도 있습니다.
$("button").closest("[data-id='normal']")
하지만 closest()만 사용하자고 jquery를 임포트하는 것은 매우 비효율적이죠.
console.log(button.closest("div"));
하지만 이렇게 자바스크립트에서 사용할 수 있습니다.
// 만약에 드롭다운과 같은 메뉴에서 바깥쪽을 클릭할 때의 예
if (!evt.target.closest(".menu-dropdown")) {
menu.classList.add("is-hidden");
navigation.classList.remove("is-expanded");
}
만약 가까운 요소에 menu-dropdown이 없다면 닫아버리는 것은 쉽게 위와같이 구현가능합니다.
function TableView({ users }) {
function handleClick(evt) {
var userId = evt.currentTarget
.closest("[data-userid]")
.getAttribute("data-userid");
// do something with `userId`
}
return (
<table>
{users.map((user) => (
<tr key={user.id} data-userid={user.id}>
<td>{user.name}</td>
<td>{user.email}</td>
<td>
<button onClick={handleClick}>Edit</button>
</td>
</tr>
))}
</table>
);
}
리액트에서는 위와 같이 사용될 수 있습니다.
가장 가까운 요소의 user.id를 가져올 수 있겠지요.
See the Pen Modal Example with `Element.closest` by YoungMinKim (@oinochoe) on CodePen.
위와 같은 예시로 모달을 닫을 수도 있습니다. esc 눌렀을 때 닫히는 것은 보너스 기능으로 넣어보았습니다.
closest() DOM API는 94% 이상을 지원하지만 여전히 IE는 내년에 사라지더라도 존재하기 때문에 IE를 위해서는 여전히 jquery의 closest()를 사용해야 합니다.
감사합니다.
출처 : https://css-tricks.com/practical-use-cases-for-javascripts-closest-method/
'Javascript' 카테고리의 다른 글
미디어쿼리를 자바스크립트에서 사용해야될 때 (0) | 2021.10.05 |
---|---|
127가지 Javascript 유용한 스니펫 (1) (0) | 2021.09.12 |
Javascript Clean Code에 관하여 (0) | 2021.04.11 |
<script async> / <script defer> 언제 사용하면 좋을까? (0) | 2021.03.02 |
Async/Await를 try/catch 없이 사용하기 (0) | 2021.03.01 |
댓글