DOM-Techniken: übergeordnete, untergeordnete und benachbarte Elemente. DOM-Manipulation in reinem JavaScript. Zählen untergeordneter Knoten

💖 Gefällt es dir? Teilen Sie den Link mit Ihren Freunden

Normalerweise verwenden Entwickler jQuery, wenn sie etwas mit dem DOM tun müssen. Allerdings kann nahezu jede DOM-Manipulation in reinem JavaScript mithilfe der DOM-API durchgeführt werden.

Schauen wir uns diese API genauer an:

Am Ende schreiben Sie Ihre eigene einfache DOM-Bibliothek, die in jedem Projekt verwendet werden kann.

DOM-Abfragen

DOM-Abfragen werden mit der Methode .querySelector() durchgeführt, die einen beliebigen CSS-Selektor als Argument verwendet.

Const myElement = document.querySelector("#foo > div.bar")

Es wird das erste passende Element zurückgegeben. Sie können das Gegenteil tun – prüfen Sie, ob das Element mit dem Selektor übereinstimmt:

MyElement.matches("div.bar") === true

Wenn Sie alle Elemente abrufen möchten, die einem Selektor entsprechen, verwenden Sie das folgende Konstrukt:

Const myElements = document.querySelectorAll(".bar")

Wenn Sie wissen was übergeordnetes Element Wenn Sie einen Verweis benötigen, können Sie einfach unter den untergeordneten Elementen suchen, anstatt den gesamten Code zu durchsuchen:

Const myChildElemet = myElement.querySelector("input") // Statt: // document.querySelector("#foo > div.bar input")

Es stellt sich die Frage: Warum dann andere, weniger praktische Methoden wie .getElementsByTagName() verwenden? Es gibt ein kleines Problem: Die Ausgabe von .querySelector() wird nicht aktualisiert und wenn wir ein neues Element hinzufügen (siehe ), ändert es sich nicht.

Const elements1 = document.querySelectorAll("div") const elements2 = document.getElementsByTagName("div") const newElement = document.createElement("div") document.body.appendChild(newElement) elements1.length === elements2.length // FALSCH

Außerdem sammelt querySelectorAll() alles in einer Liste, was es nicht sehr effizient macht.

Wie arbeite ich mit Listen?

Darüber hinaus weist .querySelectorAll() zwei kleine Einschränkungen auf. Sie können nicht einfach Methoden für die Ergebnisse aufrufen und erwarten, dass sie auf jedes einzelne angewendet werden (wie Sie es vielleicht von jQuery gewohnt sind). In jedem Fall müssen Sie alle Elemente in einer Schleife durchlaufen. Zweitens ist das zurückgegebene Objekt eine Liste von Elementen und kein Array. Daher funktionieren Array-Methoden nicht. Natürlich gibt es Methoden für Listen, etwa .forEach() , aber leider sind sie nicht für alle Fälle geeignet. Daher ist es besser, die Liste in ein Array umzuwandeln:

// Verwenden von Array.from() Array.from(myElements).forEach(doSomethingWithEachElement) // Oder Array-Prototyp (vor ES6) Array.prototype.forEach.call(myElements, doSomethingWithEachElement) // Einfacher: .forEach.call( myElements , doSomethingWithEachElement)

Jedes Element verfügt über einige Eigenschaften, die auf eine „Familie“ verweisen.

MyElement.children myElement.firstElementChild myElement.lastElementChild myElement. previousElementSibling myElement.nextElementSibling

Da die Element-Schnittstelle von der Node-Schnittstelle geerbt wird, sind auch die folgenden Eigenschaften vorhanden:

MyElement.childNodes myElement.firstChild myElement.lastChild myElement. previousSibling myElement.nextSibling myElement.parentNode myElement.parentElement

Die ersten Eigenschaften beziehen sich auf das Element und die letzten (mit Ausnahme von .parentElement) können Listen von Elementen beliebigen Typs sein. Dementsprechend können Sie den Elementtyp überprüfen:

MyElement.firstChild.nodeType === 3 // Dieses Element wird ein Textknoten sein

Klassen und Attribute hinzufügen

Das Hinzufügen einer neuen Klasse ist sehr einfach:

MyElement.classList.add("foo") myElement.classList.remove("bar") myElement.classList.toggle("baz")

Das Hinzufügen einer Eigenschaft zu einem Element erfolgt auf die gleiche Weise wie für jedes andere Objekt:

// Den Attributwert abrufen const value = myElement.value // Das Attribut als Elementeigenschaft festlegen myElement.value = "foo" // Для установки нескольких свойств используйте.Object.assign() Object.assign(myElement, { value: "foo", id: "bar" }) // Удаление атрибута myElement.value = null !}

Sie können die Methoden .getAttibute() , .setAttribute() und .removeAttribute() verwenden. Sie ändern sofort die HTML-Attribute des Elements (im Gegensatz zu den DOM-Eigenschaften), was zu einem erneuten Rendern des Browsers führt (Sie können alle Änderungen sehen, indem Sie das Element mit den Entwicklertools des Browsers untersuchen). Solche Neuzeichnungen erfordern nicht nur mehr Ressourcen als das Festlegen von DOM-Eigenschaften, sondern können auch zu unerwarteten Fehlern führen.

Typischerweise werden sie für Elemente verwendet, die keine entsprechenden DOM-Eigenschaften haben, wie zum Beispiel colspan . Oder wenn ihre Verwendung wirklich notwendig ist, beispielsweise für HTML-Eigenschaften bei der Vererbung (siehe).

CSS-Stile hinzufügen

Sie werden auf die gleiche Weise wie andere Eigenschaften hinzugefügt:

MyElement.style.marginLeft = "2em"

Einige spezifische Eigenschaften können mit .style festgelegt werden, aber wenn Sie die Werte nach einigen Berechnungen erhalten möchten, ist es besser, window.getComputedStyle() zu verwenden. Diese Methode empfängt ein Element und gibt eine CSSStyleDeclaration zurück, die die Stile sowohl des Elements selbst als auch seines übergeordneten Elements enthält:

Window.getComputedStyle(myElement).getPropertyValue("margin-left")

Ändern des DOM

Sie können Elemente verschieben:

// Element1 als letztes Kind von Element2 anhängen element1.appendChild(element2) // Element2 als Kind von Element1 vor Element3 einfügen element1.insertBefore(element2, element3)

Wenn Sie es nicht verschieben möchten, aber eine Kopie einfügen müssen, verwenden Sie:

// Einen Klon erstellen const myElementClone = myElement.cloneNode() myParentElement.appendChild(myElementClone)

Die Methode .cloneNode() akzeptiert einen booleschen Wert als Argument. Wenn dieser Wert wahr ist, werden auch untergeordnete Elemente geklont.

Natürlich können Sie neue Elemente erstellen:

Const myNewElement = document.createElement("div") const myNewTextNode = document.createTextNode("some text")

Und fügen Sie sie dann wie oben gezeigt ein. Sie können ein Element nicht direkt löschen, aber Sie können dies über das übergeordnete Element tun:

MyParentElement.removeChild(myElement)

Sie können sich auch indirekt an uns wenden:

MyElement.parentNode.removeChild(myElement)

Methoden für Elemente

Jedes Element verfügt über Eigenschaften wie .innerHTML und .textContent , sie enthalten HTML-Code und dementsprechend den Text selbst. Das folgende Beispiel ändert den Inhalt eines Elements:

// HTML ändern myElement.innerHTML = ` Neuer Inhalt ( el.addEventListener("change", function (event) ( console.log(event.target.value) )) ))

Verhindern von Standardaktionen

Verwenden Sie dazu die Methode .preventDefault(), die Standardaktionen blockiert. Beispielsweise wird die Formularübermittlung blockiert, wenn die clientseitige Autorisierung nicht erfolgreich war:

MyForm.addEventListener("submit", Funktion (Ereignis) ( const name = this.querySelector("#name") if (name.value === "Donald Duck") { alert("You gotta be kidding!") event.preventDefault() } }) !}

Die Methode .stopPropagation() hilft, wenn Sie einem untergeordneten Element einen bestimmten Event-Handler und dem übergeordneten Element einen zweiten Event-Handler für dasselbe Ereignis zugewiesen haben.

Wie bereits erwähnt, akzeptiert die Methode .addEventListener() ein optionales drittes Argument in Form eines Konfigurationsobjekts. Dieses Objekt muss eine der folgenden booleschen Eigenschaften enthalten (standardmäßig alle auf „false“ gesetzt):

  • Capture: Das Ereignis wird vor jedem anderen Element unten im DOM an dieses Element angehängt.
  • einmal: ein Ereignis kann nur einmal zugewiesen werden;
  • passiv: event.preventDefault() wird ignoriert (Ausnahme bei Fehler).

Die gebräuchlichste Eigenschaft ist .capture und sie kommt so häufig vor, dass es dafür eine Abkürzung gibt: Anstatt sie in einem Konfigurationsobjekt zu übergeben, übergeben Sie einfach ihren Wert hier:

MyElement.addEventListener(type, listener, true)

Handler werden mit der Methode .removeEventListener() entfernt, die zwei Argumente benötigt: den Ereignistyp und einen Verweis auf den zu entfernenden Handler. Die Once-Eigenschaft kann beispielsweise so implementiert werden:

MyElement.addEventListener("change", Funktionslistener (Ereignis) ( console.log(event.type + " wurde ausgelöst am " + this) this.removeEventListener("change", listener) ))

Nachlass

Nehmen wir an, Sie haben ein Element und möchten einen Event-Handler für alle seine untergeordneten Elemente hinzufügen. Dann müssten Sie sie wie oben gezeigt mit der Methode myForm.querySelectorAll("input") durchlaufen. Sie können dem Formular jedoch einfach Elemente hinzufügen und deren Inhalt mithilfe von event.target überprüfen.

MyForm.addEventListener("change", function (event) ( const target = event.target if (target.matches("input")) ( console.log(target.value) ) ))

Ein weiterer Vorteil dieser Methode besteht darin, dass der Handler automatisch an neue untergeordnete Elemente angehängt wird.

Animation

Der einfachste Weg, Animationen hinzuzufügen, ist die Verwendung von CSS mit der Eigenschaft „transition“. Für mehr Flexibilität (zum Beispiel bei Spielen) ist JavaScript jedoch besser geeignet.

Es ist keine gute Idee, die Methode window.setTimeout() aufzurufen, bis die Animation endet, da Ihre Anwendung möglicherweise einfriert, insbesondere bei mobile Geräte. Es ist besser, window.requestAnimationFrame() zu verwenden, um alle Änderungen bis zum nächsten Neuzeichnen zu speichern. Es nimmt eine Funktion als Argument an, die wiederum einen Zeitstempel erhält:

Const start = window.performance.now() const duration = 2000 window.requestAnimationFrame(function fadeIn (now)) ( const progress = now - start myElement.style.opacity = progress / duration if (progress< duration) { window.requestAnimationFrame(fadeIn) } }

Auf diese Weise wird eine sehr flüssige Animation erreicht. In seinem Artikel geht Mark Brown auf dieses Thema ein.

Schreiben unserer eigenen Bibliothek

Die Tatsache, dass Sie im DOM ständig über Elemente iterieren müssen, um Operationen an Elementen auszuführen, kann im Vergleich zur jQuery-Syntax $(".foo").css((color: "red")) recht mühsam erscheinen. Aber warum schreiben Sie nicht ein paar eigene Methoden, um diese Aufgabe zu erleichtern?

Const $ = function $ (selector, context = document) ( const elements = Array.from(context.querySelectorAll(selector)) return ( elements, html (newHtml) ( this.elements.forEach(element => ( element.innerHTML = newHtml )) return this ), css (newCss) ( this.elements.forEach(element => ( Object.assign(element.style, newCss) )) return this ), on (event, handler, options) ( this.elements .forEach(element => ( element.addEventListener(event, handler, options) )) return this ) ) )

Komplexe und umfangreiche Webanwendungen sind heutzutage alltäglich geworden. Browserübergreifende und benutzerfreundliche Bibliotheken wie jQuery mit ihrer umfangreichen Funktionalität können bei der spontanen Manipulation des DOM sehr hilfreich sein. Daher ist es nicht verwunderlich, dass viele Entwickler solche Bibliotheken häufiger verwenden, als mit der nativen DOM-API zu arbeiten, mit der es viele Probleme gab. Während Browserunterschiede immer noch ein Problem darstellen, ist das DOM heute in einem besseren Zustand als vor fünf bis sechs Jahren, als jQuery immer beliebter wurde.

In diesem Artikel demonstriere ich die HTML-Manipulationsmöglichkeiten des DOM und konzentriere mich dabei auf Eltern-, Kinder- und Nachbarbeziehungen. Abschließend werde ich Informationen zur Browserunterstützung für diese Funktionen geben. Bedenken Sie jedoch, dass eine Bibliothek wie jQuery aufgrund von Fehlern und Inkonsistenzen bei der Implementierung nativer Funktionen immer noch eine gute Option ist.

Untergeordnete Knoten zählen

Zur Demonstration verwende ich Folgendes HTML-Markup, wir werden es im Laufe des Artikels mehrmals ändern:

  • Beispiel eins
  • Beispiel zwei
  • Beispiel drei
  • Beispiel vier
  • Beispiel fünf
  • Beispiel Sechs

Var myList = document.getElementById("myList"); console.log(myList.children.length); // 6 console.log(myList.childElementCount); // 6

Wie Sie sehen, sind die Ergebnisse die gleichen, obwohl die verwendeten Techniken unterschiedlich sind. Im ersten Fall verwende ich die Kindereigenschaft. Dies ist eine schreibgeschützte Eigenschaft und gibt die Sammlung von HTML-Elementen zurück, die im angeforderten Element enthalten sind. Um ihre Anzahl zu zählen, verwende ich die Längeneigenschaft dieser Sammlung.

Im zweiten Beispiel verwende ich die Methode childElementCount, die meiner Meinung nach eine übersichtlichere und möglicherweise wartbarere Methode ist (besprechen Sie dies später ausführlicher, ich glaube nicht, dass Sie Probleme haben werden, zu verstehen, was sie tut).

Ich könnte versuchen, childNodes.length (anstelle von children.length) zu verwenden, aber schauen Sie sich das Ergebnis an:

Var myList = document.getElementById("myList"); console.log(myList.childNodes.length); // 13

Es wird 13 zurückgegeben, da childNodes eine Sammlung aller Knoten, einschließlich Leerzeichen, ist. Beachten Sie dies, wenn Sie sich für den Unterschied zwischen untergeordneten Knoten und untergeordneten Elementknoten interessieren.

Überprüfen der Existenz von untergeordneten Knoten

Um zu überprüfen, ob ein Element untergeordnete Knoten hat, kann ich die Methode hasChildNodes() verwenden. Die Methode gibt einen booleschen Wert zurück, der ihre Anwesenheit oder Abwesenheit angibt:

Var myList = document.getElementById("myList"); console.log(myList.hasChildNodes()); // WAHR

Ich weiß, dass meine Liste untergeordnete Knoten hat, aber ich kann den HTML-Code so ändern, dass keine vorhanden sind. Das Markup sieht jetzt so aus:

Und hier ist das Ergebnis der erneuten Ausführung von hasChildNodes():

Console.log(myList.hasChildNodes()); // WAHR

Die Methode gibt weiterhin true zurück. Obwohl die Liste keine Elemente enthält, enthält sie ein Leerzeichen, das ein gültiger Knotentyp ist. Diese Methode berücksichtigt alle Knoten, nicht nur Elementknoten. Damit hasChildNodes() false zurückgibt, müssen wir das Markup erneut ändern:

Und nun wird das erwartete Ergebnis in der Konsole angezeigt:

Console.log(myList.hasChildNodes()); // FALSCH

Wenn ich weiß, dass ich möglicherweise auf Leerzeichen stoße, überprüfe ich natürlich zuerst, ob untergeordnete Knoten vorhanden sind, und verwende dann die Eigenschaft „nodeType“, um festzustellen, ob sich darunter Elementknoten befinden.

Untergeordnete Elemente hinzufügen und entfernen

Es gibt Techniken, mit denen Sie Elemente zum DOM hinzufügen und daraus entfernen können. Die bekannteste davon basiert auf einer Kombination der Methoden createElement() und appendChild().

Var myEl = document.createElement("div"); document.body.appendChild(myEl);

In diesem Fall erstelle ich mit der Methode createElement() und füge es dann dem Body hinzu. Es ist sehr einfach und Sie haben diese Technik wahrscheinlich schon einmal verwendet.

Aber anstatt ein speziell erstelltes Element einzufügen, kann ich auch appendChild() verwenden und einfach das vorhandene Element verschieben. Nehmen wir an, wir haben das folgende Markup:

  • Beispiel eins
  • Beispiel zwei
  • Beispiel drei
  • Beispiel vier
  • Beispiel fünf
  • Beispiel Sechs

Beispieltext

Ich kann den Speicherort der Liste mit dem folgenden Code ändern:

Var myList = document.getElementById("myList"), container = document.getElementById("c"); container.appendChild(myList);

Das endgültige DOM sieht folgendermaßen aus:

Beispieltext

  • Beispiel eins
  • Beispiel zwei
  • Beispiel drei
  • Beispiel vier
  • Beispiel fünf
  • Beispiel Sechs

Beachten Sie, dass die gesamte Liste von ihrem Platz (über dem Absatz) entfernt und anschließend vor dem abschließenden Textkörper eingefügt wurde. Während die Methode appendChild() normalerweise zum Hinzufügen von mit createElement() erstellten Elementen verwendet wird, kann sie auch zum Verschieben vorhandener Elemente verwendet werden.

Mit „removeChild()“ kann ich ein untergeordnetes Element auch vollständig aus dem DOM entfernen. So löschen Sie unsere Liste aus dem vorherigen Beispiel:

Var myList = document.getElementById("myList"), container = document.getElementById("c"); container.removeChild(myList);

Das Element wurde nun entfernt. Die Methode „removeChild()“ gibt das entfernte Element zurück, damit ich es speichern kann, falls ich es später benötige.

Var myOldChild = document.body.removeChild(myList); document.body.appendChild(myOldChild);

Es gibt auch eine ChildNode.remove()-Methode, die der Spezifikation erst vor relativ kurzer Zeit hinzugefügt wurde:

Var myList = document.getElementById("myList"); myList.remove();

Diese Methode gibt das Remote-Objekt nicht zurück und funktioniert nicht im IE (nur Edge). Und beide Methoden entfernen Textknoten auf die gleiche Weise wie Elementknoten.

Untergeordnete Elemente ersetzen

Ich kann ein vorhandenes untergeordnetes Element durch ein neues ersetzen, unabhängig davon, ob dieses neue Element vorhanden ist oder ob ich es von Grund auf neu erstellt habe. Hier ist das Markup:

Beispieltext

Var myPar = document.getElementById("par"), myDiv = document.createElement("div"); myDiv.className = "Beispiel"; myDiv.appendChild(document.createTextNode("Neuer Elementtext")); document.body.replaceChild(myDiv, myPar);

Neuer Elementtext

Wie Sie sehen können, benötigt die Methode replaceChild() zwei Argumente: das neue Element und das alte Element, das es ersetzt.

Ich kann diese Methode auch verwenden, um ein vorhandenes Element zu verschieben. Schauen Sie sich den folgenden HTML-Code an:

Beispieltext 1

Beispieltext 2

Beispieltext 3

Ich kann den dritten Absatz durch den ersten Absatz ersetzen, indem ich den folgenden Code verwende:

Var myPar1 = document.getElementById("par1"), myPar3 = document.getElementById("par3"); document.body.replaceChild(myPar1, myPar3);

Nun sieht das generierte DOM so aus:

Beispieltext 2

Beispieltext 1

Auswahl bestimmter Kinder

Es gibt einige verschiedene Wege Auswahl eines bestimmten Elements. Wie bereits gezeigt, kann ich mit der Children-Sammlung oder der childNodes-Eigenschaft beginnen. Aber schauen wir uns andere Optionen an:

Die Eigenschaften firstElementChild und lastElementChild tun genau das, was ihr Name vermuten lässt: Sie wählen das erste und letzte untergeordnete Element aus. Kehren wir zu unserem Markup zurück:

  • Beispiel eins
  • Beispiel zwei
  • Beispiel drei
  • Beispiel vier
  • Beispiel fünf
  • Beispiel Sechs

Ich kann das erste und letzte Element mithilfe dieser Eigenschaften auswählen:

Var myList = document.getElementById("myList"); console.log(myList.firstElementChild.innerHTML); // „Beispiel eins“ console.log(myList.lastElementChild.innerHTML); // „Beispiel sechs“

Ich kann auch die Eigenschaften previousElementSibling und nextElementSibling verwenden, wenn ich andere untergeordnete Elemente als das erste oder letzte auswählen möchte. Dies geschieht durch die Kombination der Eigenschaften firstElementChild und lastElementChild:

Var myList = document.getElementById("myList"); console.log(myList.firstElementChild.nextElementSibling.innerHTML); // „Beispiel zwei“ console.log(myList.lastElementChild. previousElementSibling.innerHTML); // „Beispiel fünf“

Es gibt auch ähnliche Eigenschaften firstChild , lastChild , previousSibling und nextSibling , aber sie berücksichtigen alle Arten von Knoten, nicht nur Elemente. Im Allgemeinen sind Eigenschaften, die nur Elementknoten berücksichtigen, nützlicher als solche, die alle Knoten auswählen.

Inhalte in das DOM einfügen

Ich habe bereits nach Möglichkeiten gesucht, Elemente in das DOM einzufügen. Kommen wir zu einem ähnlichen Thema und werfen einen Blick auf die neuen Funktionen zum Einfügen von Inhalten.

Erstens gibt es eine einfache insertBefore()-Methode, ähnlich wie replaceChild(), sie benötigt zwei Argumente und funktioniert sowohl mit neuen als auch mit vorhandenen Elementen. Hier ist das Markup:

  • Beispiel eins
  • Beispiel zwei
  • Beispiel drei
  • Beispiel vier
  • Beispiel fünf
  • Beispiel Sechs

Beispielabsatz

Beachten Sie den Absatz, den ich zuerst entfernen und dann vor der Liste einfügen werde, alles auf einen Schlag:

Var myList = document.getElementById("myList"), container = document.getElementBy("c"), myPar = document.getElementById("par"); container.insertBefore(myPar, myList);

Im resultierenden HTML-Code erscheint der Absatz vor der Liste und dies ist eine weitere Möglichkeit, das Element zu umbrechen.

Beispielabsatz

  • Beispiel eins
  • Beispiel zwei
  • Beispiel drei
  • Beispiel vier
  • Beispiel fünf
  • Beispiel Sechs

Wie replaceChild() benötigt insertBefore() zwei Argumente: das hinzuzufügende Element und das Element, vor dem wir es einfügen möchten.

Diese Methode ist einfach. Versuchen wir nun eine leistungsfähigere Einfügemethode: die Methode insertAdjacentHTML().

Pseudocode

$(".rightArrow").click(function() ( rightArrowParents = this.dom(); //.dom(); ist die Pseudofunktion ... sie sollte den gesamten Alarm anzeigen(rightArrowParents); ));

Die Alarmmeldung lautet:

Körper div.lol a.rightArrow

Wie kann ich das mit Javascript/jquery bekommen?

Verwenden Sie jQuery wie folgt (gefolgt von einer Lösung, die außer für das Ereignis kein jQuery verwendet, viel weniger Funktionsaufrufe, wenn das wichtig ist):

Beispiel in Echtzeit:

$(".rightArrow").click(function() ( var rightArrowParents = ; $(this).parents().addBack().not("html").each(function() ( var input = this.tagName .toLowerCase(); if (this.className) ( Eintrag += "." + this.className.replace(/ /g, "."); ) rightArrowParents.push(entry); )); alarm(rightArrowParents.join (" ")); falsch zurückgeben; )); klicken Sie hier

(In Live-Beispielen habe ich aktualisiert Klassenattribut auf einem Div wie lol multi, um den Umgang mit mehreren Klassen zu demonstrieren.)

Hier ist eine Lösung für die exakte Elementzuordnung.

Es ist wichtig zu verstehen, dass der Selektor (ist nicht echt), die Chrome-Tools anzeigen, identifizieren das Element im DOM nicht eindeutig. ( Beispielsweise wird nicht zwischen einer Liste aufeinanderfolgender Span-Elemente unterschieden. Keine Positionierungs-/Indizierungsinformationen)

$.fn.fullSelector = function () ( var path = this.parents().addBack(); var quickCss = path.get().map(function (item) ( var self = $(item), id = item .id ? "#" + item.id: "", clss = item.classList.length ? item.classList.toString().split(" ").map(function (c) ( return "." + c; )).join("") : "", name = item.nodeName.toLowerCase(), index = self.siblings(name).length ? ":nth-child(" + (self.index() + 1) + ")" : ""; if (name === "html" || name === "body") ( return name; ) return name + index + id + clss; )).join(" > ") ; return quickCss; );

Und Sie können es so verwenden:

Console.log($("some-selector").fullSelector());

Ich habe ein Stück von T.J. verschoben. Crowder bis winzig jQuery-Plugin. Ich habe die jQuery-Version verwendet, auch wenn er recht hat, dass das völlig unnötiger Overhead ist, aber ich verwende sie nur für Debugging-Zwecke, daher ist mir das egal.

Verwendung:

Verschachtelte Spanne Einfache Spanne Vor

// Ergebnis (Array): ["body", "div.sampleClass"] $("span").getDomPath(false) // Ergebnis (String): body > div.sampleClass $("span").getDomPath( ) // Ergebnis (Array): ["body", "div#test"] $("pre").getDomPath(false) // Ergebnis (string): body > div#test $("pre").getDomPath ()

Var obj = $("#show-editor-button"), path = ""; while (typeof obj.prop("tagName") != "undefiniert")( if (obj.attr("class"))( path = "."+obj.attr("class").replace(/\s /g , ".") + path; ) if (obj.attr("id"))( path = "#"+obj.attr("id") + path; ) path = " " +obj.prop( "tagName").toLowerCase() + path; obj = obj.parent(); ) console.log(path);

Hallo, diese Funktion behebt den Fehler, der damit zusammenhängt, dass das aktuelle Element nicht im Pfad angezeigt wird

Schau es dir jetzt an

$j(".wrapper").click(function(event) ( selectedElement=$j(event.target); var rightArrowParents = ; $j(event.target).parents().not("html,body") .each(function() ( var Eintrag = this.tagName.toLowerCase(); if (this.className) ( Eintrag += "." + this.className.replace(/ /g, "."); )else if (this.id)( Eintrag += "#" + this.id; ) Eintrag=replaceAll(entry,.","."); rightArrowParents.push(entry); )); rightArrowParents.reverse(); // if(event.target.nodeName.toLowerCase()=="a" || event.target.nodeName.toLowerCase()=="h1")( var input = event.target.nodeName.toLowerCase(); if (event .target.className) ( Eintrag += "." + event.target.className.replace(/ /g, "."); )else if(event.target.id)( Eintrag += "#" + event. target.id; ) rightArrowParents.push(entry); // )

Wobei $j = jQuery-Variable

Lösen Sie das Problem auch mit .. im Klassennamen

Hier ist die Ersetzungsfunktion:

Funktion escapeRegExp(str) ( return str.replace(/([.*+?^=!:$()()|\[\]\/\\])/g, "\\$1"); ) Funktion replaceAll(str, find, replace) ( return str.replace(new RegExp(escapeRegExp(find), "g"), replace); )

Hier ist eine native JS-Version, die den jQuery-Pfad zurückgibt. Ich füge auch IDs für die Elemente hinzu, falls vorhanden. Dies gibt Ihnen die Möglichkeit, den kürzesten Weg zu wählen, wenn Sie die ID im Array sehen.

Var path = getDomPath(element); console.log(path.join(" > "));

Body > section:eq(0) > div:eq(3) > section#content > section#firehose > div#firehoselist > Article#firehose-46813651 > header > h2 > span#title-46813651

Hier ist die Funktion.

Funktion getDomPath(el) ( var stack = ; while (el.parentNode != null) ( console.log(el.nodeName); var sibCount = 0; var sibIndex = 0; for (var i = 0; i< el.parentNode.childNodes.length; i++) { var sib = el.parentNode.childNodes[i]; if (sib.nodeName == el.nodeName) { if (sib === el) { sibIndex = sibCount; } sibCount++; } } if (el.hasAttribute("id") && el.id != "") { stack.unshift(el.nodeName.toLowerCase() + "#" + el.id); } else if (sibCount >1) ( stack.unshift(el.nodeName.toLowerCase() + ":eq(" + sibIndex + ")"); ) else ( stack.unshift(el.nodeName.toLowerCase()); ) el = el.parentNode ; ) return stack.slice(1); // entfernt das HTML-Element)



Freunden erzählen