부모 요소 그리고 그 부모의 부모 요소를 찾는 상위 요소 찾기, 검색 방법 중 많이 사용되는 closest()는 매우 편리합니다. 다만 이 내장함수는 모든 브라우저가 지원하지는 않는데요 ... 만약 jQuery를 사용하는 경우 동일한 메소드 closest()를 사용할 수 있습니다. 하지만 제이쿼리를 사용하지 않는 경우에는 IE에 적용하기 위해서 자바스크립트를 사용하여 구현하는 방법을 알아보려합니다.

먼저 부모 요소를 찾아 반환하는 closest()는 매우 편리합니다. 해당 요소의 부모 요소중 해당하는 선택자를 모두 찾아 간단하게 반환해줍니다. 만약 제이쿼리를 사용하지 않으며 크로스브라우징이 필요한 경우 어떻게 구현할까요?



# 순수 자바스크립트로 자신과 부모 요소 일치하는 엘리먼트 찾기
자바스크립트의 closest() 및 최신 브라우저의 closest()를 모든 브라우저에서 사용할 수 있도록 구현하여 사용하려고 합니다. DOM 확장 메소드를 추가하여 closestOne()을 사용할 수 있습니다.
HTMLElement.prototype.closestOne = function(_selector) {
  let start = this;
  while (parent) {
    // isMatch and isEqual?
    const cond1 = start.parentElement ? start.parentElement.querySelector(_selector) : null;
    const cond2 = start.matches(_selector);
    if (cond1 && cond2) return start;
    else if (!start.parentElement) return null;
    start = start.parentElement;
  }
  return null;
};

위 코드를 추가하면 closestOne(선택자) 방식으로 부모 요소와 자신에서 일치하는 엘리먼트 요소를 쉽게 찾아 반환하게 됩니다.

! closestOne() 예제보기
아래 예제에서 span 태그를 기준으로 만약 바로 위 p 태그를 찾는 경우라면 다음의 스크립트를 적용합니다.
<div>
  <p>
    <span>TEST</span>
  </p>
</div>

이제 span의 부모 요소중 p를 찾으면 되겠죠. 추가로 div 요소도 찾아보았습니다.
ele = document.querySelector('span');
ele.closestOne('p');

ele.closestOne('div');

이처럼 쉽게 원하는 부모 요소를 선택해 반환할 수 있게되었습니다.



# 상위 요소의 Class를 확인하여 찾는 경우
순수 자바스크립트를 사용하여 부모의 클래스이름을 확인하고 없는 경우 그 부모의 부모 클래스 그 다음에도 계속해서 DOM에서 클래스명으로 찾는 방법입니다.
HTMLElement.prototype.closestByClass = function(className) {
    var target = this;
    while (!target.parentElement.classList.contains(className)) {
        target = target.parentElement;
        if (target.parentElement === null) {
            throw new Error('Not found.');
        }
    }
    return target;
};

위 코드는 DOM을 확장한 방법으로 부모 요소를 루프(Loop)를 통해 원하는 클래스명을 찾아 반환합니다. 다만 위 방법은 모든 선택자 방식이 아닌 클래스 이름 찾아 반환하죠.

이 방법은 Class에만 동작하므로 만약 원하는 엘리먼트에 클래스가 없다면 간단히 추가해 사용하면 됩니다. 클래스만 선택자로 찾는다는 점과 DOM을 확장한 방법이라는 것이 특징입니다.

해당 코드를 실행할 경우 해당하는 부모 요소를 찾으면 그 부모를 반환합니다. 사용은 예를들어 아래처럼 찾습니다.
element.closestByClass('classname');

만약 test라는 클래스가 있다면? element.closestByClass('test');라고 사용하면 되겠죠!


! 상위 요소에서 태그 이름으로 찾는 경우
앞에서는 클래스명을 사용하여 상위 요소에서 존재 여부를 확인했다면 ~ 이번에는 클래스명이 아닌 태그이름으로 찾는 방법입니다. 위와 비슷하지만 태그이름으로 찾는 점이 다른 점입니다.
HTMLElement.prototype.closestTagname = function(tagName) {
  var target = this;
  if (target.tagName === tagName.toUpperCase()) return target;
  while (!target.tagName === tagName.toUpperCase()) {
    target = target.parentElement;
    if (target.parentElement === null) {
      throw new Error('Not found.');
    }
  }
return target.parentElement;

여기까지 자신이 속한 상위 요소에 특정 클래스명 또는 태그 이름의 요소가 존재하는지 확인하는 코드를 알아보았습니다.