96 votes

Trouver l'élément le plus proche sans jQuery

J'essaie de trouver l'élément le plus proche avec un nom de balise spécifique sans jquery. Lorsque je clique sur un <th> Je veux avoir accès à la <tbody> pour cette table. Des suggestions ? J'ai lu des articles sur le décalage mais je n'ai pas trop compris. Devrais-je simplement utiliser :

Supposons que th est déjà fixé à l'élément cliqué th

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

137voto

oriadam Points 3663

Très simple :

el.closest('tbody')

Pris en charge par tous les navigateurs, sauf IE.
UPDATE : Edge le supporte maintenant aussi.

Pas besoin de jQuery. De plus, le remplacement de la fonction de jQuery $(this).closest('tbody') con $(this.closest('tbody')) augmentera les performances, de manière significative lorsque l'élément n'est pas trouvé.

Polyfill pour IE :

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;
    }
};

Notez qu'il n'y a pas de return lorsque l'élément n'a pas été trouvé, renvoyant effectivement undefined lorsque l'élément le plus proche n'a pas été trouvé.

Pour plus de détails, voir : https://developer.mozilla.org/en-US/docs/Web/API/Element/closest

71voto

Ales Points 886

Un peu (très) en retard à la fête, mais quand même. Cela devrait faire l'affaire astuce :

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;
}

23voto

Joon Points 1132

Voici comment obtenir l'élément le plus proche par nom de balise sans 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');

9voto

david1995 Points 165

Il existe une fonction normalisée pour ce faire : Élément.le plus proche . La plupart des navigateurs, sauf IE11, le supportent ( détails par caniuse.com ). Le site Documents MDN incluent également un polyfill au cas où vous devriez cibler des navigateurs plus anciens.

Pour trouver le plus proche tbody parent donné un th que vous pourriez faire :

th.closest('tbody');

Si vous voulez écrire la fonction vous-même, voici ce que j'ai trouvé :

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

Pour trouver le parent le plus proche par nom de balise, vous pouvez l'utiliser comme suit :

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

6voto

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

Cette solution utilise certaines des fonctionnalités les plus récentes de la spécification HTML 5, et son utilisation sur des navigateurs plus anciens/incompatibles (lire : Internet Explorer) nécessitera un polyfill.

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X