JavaScript: Wie erhalte ich ein übergeordnetes Element durch einen Selektor?

Lesezeit: 5 Minuten

Benutzer-Avatar
nkuhta

Beispiel:

<div someAttr="parentDiv. We need to get it from child.">
    <table>
        ...
        <td> <div id="myDiv"></div> </td>
        ...
    </table>
</div>

Ich möchte das übergeordnete Element durch einen Selektor aus dem inneren div-Element (dem mit der myDiv Klasse).

Wie erreiche ich das mit einfachem JavaScript, ohne jQuery?

Etwas wie:

var div = document.getElementById('myDiv');
div.someParentFindMethod('some selector');

  • Google gibt überall nur jQuery.parent aus.

    – nkuhta

    9. Januar 2013 um 15:10 Uhr

  • Mögliches Duplikat von Find the next ancestor element that has a specific class

    – Wadzim

    8. Dezember 2016 um 14:54 Uhr

  • Bitte aktualisieren Sie die ausgewählte Antwort pro Vorschlag von @soullivaneuh unten.

    – vhs

    2. September 2018 um 9:54 Uhr


  • Jquery am nächsten für Leute, die nicht die Einschränkung haben, JQuery nicht zu verwenden – api.jquery.com/closest

    – Sahil Singh

    13. Juni 2021 um 19:29 Uhr

Benutzer-Avatar
Georg Kargakis

Sie dürfen verwenden closest() in modernen Browsern:

var div = document.querySelector('div#myDiv');
div.closest('div[someAtrr]');

Verwenden Sie die Objekterkennung, um a Polyfill oder alternative Methode für die Abwärtskompatibilität mit IE.

  • Wenn man bedenkt, dass wir uns im Jahr 2018 befinden und Edge diese Methode unterstützt, denke ich, dass diese Antwort die akzeptierte sein sollte. 🙂

    – Soullivaneuh

    10. August 2018 um 13:58 Uhr

  • Fügen Sie einfach diese Füllwatte hinzu: github.com/jonathantneal/closest. Auch auf npm verfügbar: npmjs.com/package/element-closest.

    – Fabian von Ellerts

    27. November 2018 um 16:47 Uhr

  • Jetzt sind wir im Jahr 2021, also ist das mehr als akzeptabel. Das ist jetzt die beste Antwort.

    – unterzeichnen

    21. Januar 2021 um 21:10 Uhr

  • Es ist 2022. Lassen Sie uns das akzeptieren.

    – David R. Myers

    27. Januar um 14:48 Uhr

  • Du wirst vielleicht nie akzeptiert, aber du bekommst unsere Liebe.

    – Akshay K. Nair

    1. Februar um 5:18

Benutzer-Avatar
Chris

Hier ist die einfachste Version:

function collectionHas(a, b) { //helper function (see below)
    for(var i = 0, len = a.length; i < len; i ++) {
        if(a[i] == b) return true;
    }
    return false;
}
function findParentBySelector(elm, selector) {
    var all = document.querySelectorAll(selector);
    var cur = elm.parentNode;
    while(cur && !collectionHas(all, cur)) { //keep going up until you find a match
        cur = cur.parentNode; //go up
    }
    return cur; //will return null if not found
}

var yourElm = document.getElementById("yourElm"); //div in your original code
var selector = ".yes";
var parent = findParentBySelector(yourElm, selector);

  • Dies ist insofern ziemlich ineffizient, als es alle Elemente mit diesem Selektor im gesamten Dokument abruft, anstatt nur das übergeordnete Element zu überprüfen.

    Benutzer663031

    5. Oktober 2016 um 12:58 Uhr

  • Dies JSPerf-Test Analysen Element.matches(), Element.closest(), und eine Polyfill für jede dieser Methoden. Die Füllwatte für Element.matches() sieht deiner Implementierung sehr ähnlich. Um die Leistungsbedenken von @ user663031 auszuräumen, könnten Sie vielleicht verwenden Element.matches() Anstatt von Document.querySelectorAll(). Es scheint schneller zu laufen als die verwandte Polyfill.

    – Ryan v

    3. März 2020 um 18:16 Uhr


  • Stimme user663031 zu

    – Don Nisnoni

    12. April 2020 um 20:02 Uhr

Findet das nächste übergeordnete Element (oder das Element selbst), das mit dem angegebenen Selektor übereinstimmt. Ebenfalls enthalten ist ein Selektor zum Beenden der Suche, falls Sie einen gemeinsamen Vorfahren kennen, bei dem Sie die Suche beenden sollten.

function closest(el, selector, stopSelector) {
  var retval = null;
  while (el) {
    if (el.matches(selector)) {
      retval = el;
      break
    } else if (stopSelector && el.matches(stopSelector)) {
      break
    }
    el = el.parentElement;
  }
  return retval;
}

  • next ist ein beschissener Name, sollte “closestAncestor” heißen, wenn der nächste Vorfahr 10 Elemente nach oben und der nächste Nachkomme 1 Kind nach unten ist, ist der “nächste” der Nachkomme, nicht der Vorfahr, aber diese Funktion gibt den Vorfahren zurück stattdessen

    – Hansenrik

    3. August 2021 um 11:50 Uhr

Verwenden der Antwort von Leech mit indexOf (zur Unterstützung von IE)

Dies verwendet das, worüber Blutegel gesprochen hat, aber damit es für IE funktioniert (IE unterstützt keine Übereinstimmungen):

function closest(el, selector, stopSelector) {
  var retval = null;
  while (el) {
    if (el.className.indexOf(selector) > -1) {
      retval = el;
      break
    } else if (stopSelector && el.className.indexOf(stopSelector) > -1) {
      break
    }
    el = el.parentElement;
  }
  return retval;
}

Es ist nicht perfekt, aber es funktioniert, wenn der Selektor eindeutig genug ist, damit er nicht versehentlich mit dem falschen Element übereinstimmt.

Benutzer-Avatar
Gabriel Salinas Szada

Durch die Nutzung querySelector() und am nächsten () Methoden ist es möglich, das übergeordnete Element zu erhalten.

  • querySelector() gibt das erste Element zurück, das mit einem oder mehreren angegebenen CSS-Selektoren im Dokument übereinstimmt.

  • closest() durchsucht den DOM-Baum nach dem nächsten Element, das mit einem angegebenen CSS-Selektor übereinstimmt.

Anwendungsbeispiel

var element = document.querySelector('td');
console.log(element.closest('div'));
<div>
  <table>
    <tr>
      <td></td>
    </tr>
  </table>
</div>

Falls Sie mehr als ein Element auswählen müssen, querySelectorAll() ist eine gute Passform.

  • querySelectorAll() gibt alle Elemente im Dokument, die mit einem oder mehreren angegebenen CSS-Selektoren übereinstimmen, als statisches NodeList-Objekt zurück.

Um das gewünschte Element auszuwählen, muss es im Inneren angegeben werden [] so wäre zum Beispiel für das zweite Element: element[1]

Im folgenden Beispiel closest() -Methode wird verwendet, um das übergeordnete Element zu erhalten <tr> Element eines bestimmten ausgewählten Elements.

var element = document.querySelectorAll('td');
console.log(element[1].closest('tr'));
<div>
  <table>
    <tr id="1">
      <td> First text </td>
    </tr>
    <tr id="2">
      <td> Second text </td>
    </tr>
  </table>
</div>

Hier ist eine rekursive Lösung:

function closest(el, selector, stopSelector) {
  if(!el || !el.parentElement) return null
  else if(stopSelector && el.parentElement.matches(stopSelector)) return null
  else if(el.parentElement.matches(selector)) return el.parentElement
  else return closest(el.parentElement, selector, stopSelector)
}

Benutzer-Avatar
Joel Teply

Ich dachte, ich würde ein viel robusteres Beispiel liefern, auch in Typoskript, aber es wäre einfach, es in reines Javascript umzuwandeln. Diese Funktion fragt Eltern ab, indem sie entweder die ID wie “#my-element” oder die Klasse “.my-class” verwendet und im Gegensatz zu einigen dieser Antworten mehrere Klassen verarbeitet. Ich habe festgestellt, dass ich einige ähnlich benannt habe und die obigen Beispiele die falschen Dinge gefunden haben.

function queryParentElement(el:HTMLElement | null, selector:string) {
    let isIDSelector = selector.indexOf("#") === 0
    if (selector.indexOf('.') === 0 || selector.indexOf('#') === 0) {
        selector = selector.slice(1)
    }
    while (el) {
        if (isIDSelector) {
            if (el.id === selector) {
                return el
            }
        }
        else if (el.classList.contains(selector)) {
            return el;
        }
        el = el.parentElement;
    }
    return null;
}

So wählen Sie nach Klassennamen aus:

let elementByClassName = queryParentElement(someElement,".my-class")

So wählen Sie nach ID aus:

let elementByID = queryParentElement(someElement,"#my-element")

1217000cookie-checkJavaScript: Wie erhalte ich ein übergeordnetes Element durch einen Selektor?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy