[javascript] jQuery없이 가장 가까운 요소 찾기

jquery없이 특정 태그 이름을 가진 가장 가까운 요소를 찾으려고합니다. 를 클릭하면 해당 테이블에 대한 <th>액세스 권한을 얻고 싶습니다 <tbody>. 제안? 오프셋에 대해 읽었지만 너무 많이 이해하지 못했습니다. 그냥 사용해야할까요?

th가 이미 클릭 된 요소로 설정되어 있다고 가정합니다.

th.offsetParent.getElementsByTagName('tbody')[0]



답변

파티에 조금 늦었지만 그럼에도 불구하고. 이것은 트릭을 해야합니다 .

function closest(el, selector) {
    var matchesFn;

    // find vendor prefix
    ['matches','webkitMatchesSelector','mozMatchesSelector','msMatchesSelector','oMatchesSelector'].some(function(fn) {
        if (typeof document.body[fn] == 'function') {
            matchesFn = fn;
            return true;
        }
        return false;
    })

    var parent;

    // traverse parents
    while (el) {
        parent = el.parentElement;
        if (parent && parent[matchesFn](selector)) {
            return parent;
        }
        el = parent;
    }

    return null;
}


답변

매우 간단합니다.

el.closest('tbody')

IE를 제외한 모든 브라우저에서 지원됩니다.
업데이트 : Edge도 이제 지원합니다.

jQuery가 필요 없습니다. 더 이상 교체 jQuery를이다 $(this).closest('tbody')$(this.closest('tbody'))요소가 발견되지 크게하면 성능을 향상시킬 것입니다.

IE 용 Polyfill :

if (!Element.prototype.matches) Element.prototype.matches = Element.prototype.msMatchesSelector;
if (!Element.prototype.closest) Element.prototype.closest = function (selector) {
    var el = this;
    while (el) {
        if (el.matches(selector)) {
            return el;
        }
        el = el.parentElement;
    }
};

return요소를 찾을 수 없는 경우가 없으며 undefined가장 가까운 요소를 찾을 수 없을 때 효과적으로 반환 됩니다.

자세한 내용은 https://developer.mozilla.org/en-US/docs/Web/API/Element/closest를 참조하십시오.


답변

다음은 jQuery없이 태그 이름으로 가장 가까운 요소를 가져 오는 방법입니다.

function getClosest(el, tag) {
  // this is necessary since nodeName is always in upper case
  tag = tag.toUpperCase();
  do {
    if (el.nodeName === tag) {
      // tag name is found! let's return it. :)
      return el;
    }
  } while (el = el.parentNode);

  // not found :(
  return null;
}

getClosest(th, 'tbody');


답변

이를 수행하는 표준화 된 함수가 있습니다 : Element.closest . IE11을 제외한 대부분의 브라우저가이를 지원합니다 ( caniuse.com의 세부 사항 ). MDN 워드 프로세서는 또한 이전 버전의 브라우저를 대상으로 할 경우에 polyfill을 포함한다.

tbody주어진 가장 가까운 부모 를 찾으려면 th다음을 수행하십시오.

th.closest('tbody');

직접 함수를 작성하려는 경우-여기에 내가 생각 해낸 것이 있습니다.

function findClosestParent (startElement, fn) {
  var parent = startElement.parentElement;
  if (!parent) return undefined;
  return fn(parent) ? parent : findClosestParent(parent, fn);
}

태그 이름으로 가장 가까운 부모를 찾으려면 다음과 같이 사용할 수 있습니다.

findClosestParent(x, element => return element.tagName === "SECTION");


답변

function closest(el, sel) {
    if (el != null)
        return el.matches(sel) ? el
            : (el.querySelector(sel)
                || closest(el.parentNode, sel));
}

이 솔루션은 HTML 5 사양의 최신 기능 중 일부를 사용하며 이전 / 호환되지 않는 브라우저 (읽기 : Internet Explorer)에서이를 사용하려면 폴리 필이 필요합니다.

Element.prototype.matches = (Element.prototype.matches || Element.prototype.mozMatchesSelector
    || Element.prototype.msMatchesSelector || Element.prototype.oMatchesSelector
    || Element.prototype.webkitMatchesSelector || Element.prototype.webkitMatchesSelector);


답변

@SalmanPK 답변을 확장하려면

마우스 오버와 같은 이벤트로 작업 할 때 유용한 선택기로 노드를 사용할 수 있습니다.

function closest(el, selector) {
    if (typeof selector === 'string') {
        matches = el.webkitMatchesSelector ? 'webkitMatchesSelector' : (el.msMatchesSelector ? 'msMatchesSelector' : 'matches');
        while (el.parentElement) {
            if (el[matches](selector)) {
                return el
            };
            el = el.parentElement;
        }
    } else {
        while (el.parentElement) {
            if (el === selector) {
                return el
            };
            el = el.parentElement;
        }
    }

    return null;
}


답변

내가 사용하는 간단한 기능은 다음과 같습니다.

function closest(el, selector) {
    var matches = el.webkitMatchesSelector ? 'webkitMatchesSelector' : (el.msMatchesSelector ? 'msMatchesSelector' : 'matches');

    while (el.parentElement) {
        if (el[matches](selector)) return el;

        el = el.parentElement;
    }

    return null;
}