Wie kann ich überprüfen, ob ein Element im sichtbaren DOM vorhanden ist?

421

Wie testet man ein Element ohne Verwendung der getElementByIdMethode auf Existenz ?

Ich habe eine Live-Demo als Referenz eingerichtet. Ich werde den Code auch hier ausdrucken:

<!DOCTYPE html>
<html>
<head>
    <script>
    var getRandomID = function (size) {
            var str = "",
                i = 0,
                chars = "0123456789abcdefghijklmnopqurstuvwxyzABCDEFGHIJKLMNOPQURSTUVWXYZ";
            while (i < size) {
                str += chars.substr(Math.floor(Math.random() * 62), 1);
                i++;
            }
            return str;
        },
        isNull = function (element) {
            var randomID = getRandomID(12),
                savedID = (element.id)? element.id : null;
            element.id = randomID;
            var foundElm = document.getElementById(randomID);
            element.removeAttribute('id');
            if (savedID !== null) {
                element.id = savedID;
            }
            return (foundElm) ? false : true;
        };
    window.onload = function () {
        var image = document.getElementById("demo");
        console.log('undefined', (typeof image === 'undefined') ? true : false); // false
        console.log('null', (image === null) ? true : false); // false
        console.log('find-by-id', isNull(image)); // false
        image.parentNode.removeChild(image);
        console.log('undefined', (typeof image === 'undefined') ? true : false); // false ~ should be true?
        console.log('null', (image === null) ? true : false); // false ~ should be true?
        console.log('find-by-id', isNull(image)); // true ~ correct but there must be a better way than this?
    };
    </script>
</head>
<body>
    <div id="demo"></div>
</body>
</html>

Grundsätzlich zeigt der obige Code, dass ein Element in einer Variablen gespeichert und dann aus dem DOM entfernt wird. Obwohl das Element aus dem DOM entfernt wurde, behält die Variable das Element bei, wie es beim ersten Deklarieren war. Mit anderen Worten, es handelt sich nicht um eine Live-Referenz auf das Element selbst, sondern um eine Nachbildung. Infolgedessen führt das Überprüfen des Werts der Variablen (des Elements) auf Existenz zu einem unerwarteten Ergebnis.

Die isNullFunktion ist mein Versuch, anhand einer Variablen zu prüfen, ob Elemente vorhanden sind, und sie funktioniert. Ich möchte jedoch wissen, ob es einen einfacheren Weg gibt, dasselbe Ergebnis zu erzielen.

PS: Ich bin auch daran interessiert, warum sich JavaScript-Variablen so verhalten, wenn jemand einige gute Artikel zum Thema kennt.

Justin Bull
quelle
18
Eigentlich ist es eine Live-Referenz auf das Element selbst, es ist einfach nicht mehr in einem Dokument. Diese Funktionalität ist erforderlich, da Sie ein Element tatsächlich aus dem DOM ziehen und später wieder einfügen können, wobei alle Event-Handler / etc noch daran angehängt sind. Warum verhalten sich JS-Variablen so? Weil es unglaublich nervig wäre, wenn sie es nicht tun würden. JS löscht Variablen nur, wenn Sie keine Verweise mehr darauf haben. Die Sprache kann nicht wissen, welche Referenzen Sie für wichtig halten und welche Sie für wertlos halten.
Mark Kahn
@wölfe Interessant. Ich habe das schon oft erlebt und nie wirklich viel darüber nachgedacht. Tatsächlich speichere ich in meinem aktuellen Projekt Elemente in einem Array, bevor ich Änderungen daran vornehme, nur für den Fall, dass ich die Änderungen rückgängig machen möchte.
Justin Bull
1
Die Speicherbereinigung wird von Zeit zu Zeit ausgeführt und löscht alles, was sie für möglich hält. Es scheint in den meisten Browsern ziemlich mies zu sein, wird aber immer besser, da Entwickler feststellen, dass einige Browser zwischen Neustarts tagelang oder wochenlang ausgeführt werden. Daher ist eine gute Speicherbereinigung für die Browserleistung von entscheidender Bedeutung. Webentwickler können helfen, indem sie Eigenschaften (und damit Verweise auf Dinge im Speicher) löschen, die nicht mehr benötigt werden.
RobG
2
@JustinBull Seien Sie vorsichtig beim Speichern von Kopien der Elemente, die zurückgesetzt werden sollen. Beim Speichern eines DOM-Elements in einem Array wird ein Verweis auf das DOM-Element und keine Kopie gespeichert, sodass Änderungen am DOM-Element beim Verweisen auf das Element des Arrays berücksichtigt werden. Dies ist bei allen Objekten in Javascript der Fall (Variablen vom Typ 'Objekt').
Anthony DiSanti

Antworten:

544

Es scheint, dass einige Leute hier landen und einfach wissen wollen, ob ein Element existiert (ein bisschen anders als die ursprüngliche Frage).

Dies ist so einfach wie die Verwendung einer Auswahlmethode des Browsers und die Überprüfung auf einen wahrheitsgemäßen Wert (im Allgemeinen).

Wenn mein Element beispielsweise ein idvon hätte "find-me", könnte ich einfach ...

var elementExists = document.getElementById("find-me");

Dies wird angegeben, um entweder einen Verweis auf das Element zurückzugeben oder null. Wenn Sie einen booleschen Wert haben müssen, werfen Sie einfach einen !!vor dem Methodenaufruf.

Darüber hinaus können Sie einige der vielen anderen Methoden verwenden, um Elemente zu finden, z. B. (alle leben davon document):

  • querySelector()/.querySelectorAll()
  • getElementsByClassName()
  • getElementsByName()

Einige dieser Methoden geben a zurück. NodeListÜberprüfen Sie daher unbedingt seine lengthEigenschaft, da a NodeListein Objekt ist und daher wahr ist .


Um tatsächlich festzustellen, ob ein Element als Teil des sichtbaren DOM vorhanden ist (wie die ursprünglich gestellte Frage), bietet Csuwldcat eine bessere Lösung als das Rollen eines eigenen Elements (wie diese Antwort früher enthielt). Das heißt, diecontains() Methode für DOM-Elemente zu verwenden.

Sie könnten es so verwenden ...

document.body.contains(someReferenceToADomElement);
Alex
quelle
1
Genau das, wonach ich gesucht habe! Also offensichtlich lol, warum habe ich nicht daran gedacht. Kennen Sie auch gute Artikel, die erklären, warum Variablen so handeln?
Justin Bull
3
Noch kürzer:var elementInDom = function( el ) { while ( el = el.parentNode ) if ( el === document ) return true; return false; }
Bennedich
2
@ ButtleButkus Lesen Sie die aktuelle Frage. Diese von Ihnen verwendete Lösung ist nicht sinnvoll, da getElementById() sie einen Verweis auf ein DOM-Element zurückgibt oder nulldaher die Verwendung typeof(insbesondere auf der RHS) falsch ist (wenn sie nicht definiert wäre, würde die LHS-Bedingung a auslösen ReferenceError).
alex
2
Gibt es einen Grund, dies über das unten Gesagte zu verwenden: Was document.body.contains()scheint eine sehr gute Browserunterstützung zu haben?
Crush
1
@ Jonz Entfernte den alten Antwortteil, vergiss nicht, csuwldcat
alex
310

Verwenden Sie, getElementById()wenn es verfügbar ist.

Hier ist eine einfache Möglichkeit, dies mit jQuery zu tun:

if ($('#elementId').length > 0) {
  // Exists.
}

Und wenn Sie keine Bibliotheken von Drittanbietern verwenden können, halten Sie sich einfach an das Basis-JavaScript:

var element =  document.getElementById('elementId');
if (typeof(element) != 'undefined' && element != null)
{
  // Exists.
}
Kon
quelle
2
Für das Projekt, an dem ich arbeite, kann ich keine Bibliothek verwenden. Nur der alte Mode-Rohcode. Ich kenne diese jQuery-Methode, aber sie funktioniert nicht bei Elementen, die nicht im jQuery-Container enthalten sind. Zum Beispiel $('#elementId')[0].lengthwürde nicht das gleiche Ergebnis erzeugen.
Justin Bull
8
Gibt es einen guten Grund für eine so komplizierte if-Anweisung im zweiten Codebeispiel? Warum nicht einfach if (element) {}? Wenn das Element undefiniert oder null ist, ist dieser Ausdruck falsch. Wenn element ein DOM-Element ist, ist der Ausdruck wahr.
Kayahr
2
@ Kayahr Es ist viel zu kompliziert. getElementById()wird zurückgegeben, nullwenn das Element nicht gefunden wurde. Daher ist nur die Überprüfung auf einen wahrheitsgemäßen Rückgabewert erforderlich.
alex
5
Ich denke, das ist nur gesunder Menschenverstand.
Kon
8
getElementByIdsollte niemals zurückkehren undefined. In jedem Fall element != nullwürde der Scheck dies aufgreifen.
190

Mit der Node.contains DOM-API können Sie ganz einfach überprüfen, ob ein Element auf der Seite (derzeit im DOM) vorhanden ist:

document.body.contains(YOUR_ELEMENT_HERE);

CROSS-BROWSER HINWEIS : Das documentObjekt in Internet Explorer verfügt nicht über eine contains()Methode. Um die browserübergreifende Kompatibilität sicherzustellen, verwenden Sie document.body.contains()stattdessen.

csuwldcat
quelle
4
Dies scheint die ultimative Antwort auf dieses Problem zu sein ... und seine Unterstützung, wenn man davon ausgeht, dass MDN ziemlich gut ist.
Crush
2
Dies ist die beste Antwort. Beachten Sie, dass nur die Überprüfung document.contains()ausreichen sollte.
Alex
@csuwldcat Es hat bei mir funktioniert, zumindest in Chrome mit document.contains(document.documentElement). documenthat Nodean seiner Prototypenkette, soweit ich das beurteilen kann ( document-> HTMLDocument-> Document-> Node)
alex
4
Dies ist in der Tat die beste Antwort: - Es ist ein Webstandard - es wird sehr gut unterstützt (etwas überraschend erscheint es in Firefox erst in Version 9, ich vermute, weil es eine nicht standardmäßige Funktion war, die im IE erfunden wurde und nicht standardisiert bis später) - es muss das schnellste sein, da es einen einzelnen Aufruf einer nativen API verwendet
Jon z
2
@ LeeSaxon Die Syntax ist document.body.contains([selector]), dhdocument.body.contains(document.getElementById('div')
iglesiasedd
67

Ich mache einfach:

if(document.getElementById("myElementId")){
    alert("Element exists");
} else {
    alert("Element does not exist");
}

Es funktioniert bei mir und hatte noch keine Probleme damit ...

Anomalie
quelle
1
Dies hat jedoch nichts mit der ursprünglichen Frage zu tun. Das OP möchte wissen, ob ein Verweis auf ein DOM-Element Teil des sichtbaren DOM ist oder nicht.
alex
16
Hat mir aber geholfen. Ich suchte nach dem einfachen Test der Elementexistenz; das hat funktioniert. Vielen Dank.
Khaverim
1
Diese Antwort funktioniert gut, aber nur, wenn das Element eine hat id. Die bessere Lösung, die die Frage beantwortet Wie kann überprüft werden, ob das Element im sichtbaren DOM vorhanden ist? Mit jedem Element sind auch Elemente ohne ids zu tun document.body.contains(element).
Edward
@Edward Das ist etwas ganz anderescontains()
alex
Ich verstehe das. Ich habe in meinem Kommentar nur vorgeschlagen, dass andere Antworten besser und besser für die Frage geeignet sind.
Edward
11

Sie können einfach überprüfen, ob die parentNode-Eigenschaft null ist.

Das ist,

if(!myElement.parentNode)
{
    // The node is NOT in the DOM
}
else
{
    // The element is in the DOM
}
Mikrokammern
quelle
Ich weiß, dass dies eine alte Frage ist, aber diese Antwort ist genau die Art von eleganter einfacher Lösung für die Frage, nach der ich gesucht habe.
Poby
11
@poby: Es mag elegant erscheinen, aber es macht nicht wirklich das, was angefordert wurde. Es wird nur geprüft, ob das Element ein übergeordnetes Element hat. Dies bedeutet nicht, dass sich das Element im sichtbaren DOM befindet, da möglicherweise das übergeordnete Element nicht damit verbunden ist.
Kayahr
Man müsste alle Eltern durchgehen, um herauszufinden, ob das letzte Dokument ist. Das andere Problem ist, dass es sich möglicherweise immer noch außerhalb des sichtbaren Bereichs befindet oder abgedeckt ist oder aus vielen anderen Gründen nicht sichtbar ist.
Arek Bal
Ein Element kann auch einen parentNode haben, nur weil es an ein Dokumentfragment angehängt wurde.
11

Aus dem Mozilla Developer Network :

Diese Funktion prüft, ob sich ein Element im Hauptteil der Seite befindet. Da enthält () inklusive ist und die Bestimmung, ob der Körper sich selbst enthält, nicht die Absicht von isInPage ist, gibt dieser Fall explizit false zurück.

function isInPage(node) {
  return (node === document.body) ? false : document.body.contains(node);
}

Knoten ist der Knoten, nach dem wir im <body> suchen möchten.

Ekramul Hoque
quelle
+1, funktioniert dies auch für (beliebige) Textknoten (oder Kommentarknoten)?
Nikos M.
@ NikosM. Es sollte in jedem HTML-Tag funktionieren, aber ich habe es nicht getestet.
Ekramul Hoque
4
Sollte das nicht falsesein true?
Marc-André Lafortune
Wenn der nodeIS der ist document.body, sollte die Methode doch zurückkehren true? Dh,return (node === document.body) || document.body.contains(node);
daiscog
7

Die einfachste Lösung besteht darin, die baseURI- Eigenschaft zu überprüfen , die nur festgelegt wird, wenn das Element in das DOM eingefügt wird, und beim Entfernen in eine leere Zeichenfolge zurückgesetzt wird.

var div = document.querySelector('div');

// "div" is in the DOM, so should print a string
console.log(div.baseURI);

// Remove "div" from the DOM
document.body.removeChild(div);

// Should print an empty string
console.log(div.baseURI);
<div></div>

Peter Mortensen
quelle
5
Ich wusste nicht einmal, dass es auf DOM-Knoten eine baseURI-Eigenschaft gibt. Was mir an diesem Ansatz gefällt, ist, dass er eine Eigenschaft des Elements selbst verwendet, was vermutlich bedeutet, dass es auch dann funktionieren würde, wenn sich das Element in einem anderen Dokument befindet (z. B. einem Iframe). Was ich daran nicht mag, ist, dass es außerhalb von Webkit nicht zu funktionieren scheint.
DoctorDestructo
Vorsicht, da dies den folgenden Fehler auslöst, wenn sich das Element nicht im Dokument befindet : Cannot read property 'baseURI' of null. Beispiel:console.log(document.querySelector('aside').baseURI)
Ian Davis
Diese Methode kann nicht verwendet werden, da ab sofort immer dieselbe Zeichenfolge gedruckt wird.
Kagami Sascha Rosylight
4

jQuery-Lösung:

if ($('#elementId').length) {
    // element exists, do something...
}

Dies funktionierte bei mir mit jQuery und musste nicht $('#elementId')[0]verwendet werden.

Code Buster
quelle
Warum ist $('#elementId')[0]etwas zu vermeiden?
Alex
Es ist lange her, dass ich darauf geantwortet habe. Mit $ ('# elementId') [0] glaube ich, dass Sie immer angeben, dass der Wert am 0. Index liegt. Auf diese Weise suchen Sie immer nach dem ersten vorkommenden Element. Was gibt es gab mehrere Kontrollkästchen mit dem gleichen Namen, so wie ein Optionsfeld. Diesmal ist die Länge hilfreich.
Code Buster
3

Die Lösung von csuwldcat scheint die beste zu sein, aber es sind geringfügige Änderungen erforderlich, damit sie mit einem Element, das sich in einem anderen Dokument befindet als der JavaScript-Code, wie z. B. einem Iframe, ordnungsgemäß funktioniert.

YOUR_ELEMENT.ownerDocument.body.contains(YOUR_ELEMENT);

Beachten Sie die Verwendung der ownerDocumentEigenschaft des Elements im Gegensatz zu einfach nur alt document(die sich möglicherweise auf das Eigentümerdokument des Elements bezieht oder nicht).

torazaburo hat eine noch einfachere Methode veröffentlicht , die auch mit nicht lokalen Elementen funktioniert. Leider wird die baseURIEigenschaft verwendet, die derzeit nicht einheitlich in allen Browsern implementiert ist (ich konnte sie nur in den WebKit- basierten Elementen zum Laufen bringen ). Ich konnte keine anderen Element- oder Knoteneigenschaften finden, die auf ähnliche Weise verwendet werden könnten, daher denke ich, dass die oben genannte Lösung vorerst so gut ist, wie es nur geht.

DoctorDestructo
quelle
3

Anstatt Eltern zu iterieren, können Sie einfach das Begrenzungsrechteck erhalten, das alle Nullen enthält, wenn das Element vom DOM getrennt wird:

function isInDOM(element) {
    if (!element)
        return false;
    var rect = element.getBoundingClientRect();
    return (rect.top || rect.left || rect.height || rect.width)?true:false;
}

Wenn Sie den Randfall eines Elements mit der Breite und Höhe Null bei Null oben und Null links behandeln möchten, können Sie dies überprüfen, indem Sie die Eltern iterieren, bis document.body:

function isInDOM(element) {
    if (!element)
        return false;
    var rect = element.getBoundingClientRect();
    if (element.top || element.left || element.height || element.width)
        return true;
    while(element) {
        if (element == document.body)
            return true;
        element = element.parentNode;
    }
    return false;
}
Erez Pilosof
quelle
Dies führt zu einem neuen
Steven Vachon
3

Eine einfache Möglichkeit, um zu überprüfen, ob ein Element vorhanden ist, besteht in einem einzeiligen Code von jQuery.

Hier ist der Code unten:

if ($('#elementId').length > 0) {
    // Do stuff here if the element exists
} else {
    // Do stuff here if the element does not exist
}
Ravi Agrawal
quelle
2

Eine weitere Option ist element.closest :

element.closest('body') === null
Brian M. Hunt
quelle
2

Dieser Code funktioniert für mich und ich hatte keine Probleme damit.


    if(document.getElementById("mySPAN")) {
        // If the element exists, execute this code
        alert("Element exists");
    }
    else {
        // If the element does not exist execute this code
        alert("Element does not exists");
    }
Mohammad Ayoub Khan
quelle
1

Sie können auch verwenden jQuery.contains, um zu überprüfen, ob ein Element ein Nachkomme eines anderen Elements ist. Ich habe documentals übergeordnetes Element für die Suche übergeben, da alle Elemente, die auf der Seite DOM vorhanden sind, ein Nachkomme von sind document.

jQuery.contains( document, YOUR_ELEMENT)
Nitinkhuranas
quelle
1

Überprüfen Sie, ob das Element ein untergeordnetes Element von <html>via ist Node::contains():

const div = document.createElement('div');
document.documentElement.contains(div); //-> false

document.body.appendChild(div);
document.documentElement.contains(div); //-> true

Ich habe dies und mehr in is-dom-losgelöst behandelt .

Steven Vachon
quelle
1

Eine einfache Lösung mit jQuery:

$('body').find(yourElement)[0] != null
mateusmaso
quelle
2
... oder$(document).find(yourElement).length !== 0
Grinn
1
Das nutzt das aus null == undefined. Der tatsächlich zurückgegebene Wert wäre undefined. Es zu vergleichen nullist ein bisschen komisch.
Alex
1
// This will work prefectly in all :D
function basedInDocument(el) {

    // This function is used for checking if this element in the real DOM
    while (el.parentElement != null) {
        if (el.parentElement == document.body) {
            return true;
        }
        el = el.parentElement; // For checking the parent of.
    } // If the loop breaks, it will return false, meaning
      // the element is not in the real DOM.

    return false;
}
qandil afa
quelle
In allem was? Alle Fälle?
Peter Mortensen
1
  • Wenn sich ein Element in der befindet DOM , sollten auch seine Eltern in sein
  • Und der letzte Großelternteil sollte der sein document

Um zu überprüfen, ob wir nur zum parentNodeBaum des Elements gelangen, bis wir den letzten Großelternteil erreichen

Benutze das:

/**
 * @param {HTMLElement} element - The element to check
 * @param {boolean}     inBody  - Checks if the element is in the body
 * @return {boolean}
 */
var isInDOM = function(element, inBody) {
    var _ = element, last;

    while (_) {
        last = _;
        if (inBody && last === document.body) { break;}
        _ = _.parentNode;
    }

    return inBody ? last === document.body : last === document;
};
silassare
quelle
2
Dies ist möglicherweise die beste Antwort, da das DOM nicht erneut gerendert wird.
Steven Vachon
Eine Erklärung wäre angebracht (antworten Sie, indem Sie Ihre Antwort bearbeiten , nicht hier in den Kommentaren).
Peter Mortensen
0

Dieser Ansatz hat mir gefallen:

var elem = document.getElementById('elementID');

if (elem)
    do this
else
    do that

Ebenfalls

var elem = ((document.getElementById('elemID')) ? true:false);

if (elem)
    do this
else
    do that
Hugh
quelle
1
Warum nicht einfach, !!wenn Sie einen Booleschen wollen?
Alex
Wenn das Element keine ID hat, wird davon ausgegangen, dass es sich nicht im DOM befindet. Ich würde sagen, das ist falsch.
Steven Vachon
0

Verwenden Sie querySelectorAllmit forEach,

document.querySelectorAll('.my-element').forEach((element) => {
  element.classList.add('new-class');
});

als das Gegenteil von:

const myElement = document.querySelector('.my-element');
if (myElement) {
  element.classList.add('new-class');
}
Rafal Enden
quelle
0

Versuche Folgendes. Es ist die zuverlässigste Lösung:

window.getComputedStyle(x).display == ""

Zum Beispiel,

var x = document.createElement("html")
var y = document.createElement("body")
var z = document.createElement("div")
x.appendChild(y);
y.appendChild(z);

z.style.display = "block";

console.log(z.closest("html") == null); // 'false'
console.log(z.style.display); // 'block'
console.log(window.getComputedStyle(z).display == ""); // 'true'
Dexiang
quelle
1
Dies führt wahrscheinlich zu einem neuen
Steven Vachon
0

Für alle vorhandenen Elemente ist parentElement festgelegt, mit Ausnahme des HTML-Elements!

function elExists (e) { 
    return (e.nodeName === 'HTML' || e.parentElement !== null);
};
Jona
quelle
Ist es immer "HTML" ? Könnte es "html" sein ?
Peter Mortensen
x.tagName oder x.nodeName immer in Großbuchstaben, egal wie Sie es in Ihren Code schreiben
Jonah
0

dieser Zustand Küken alle Fälle.

function del() {
//chick if dom has this element 
//if not true condition means null or undifind or false .

if (!document.querySelector("#ul_list ")===true){

// msg to user
    alert("click btn load ");

// if console chick for you and show null clear console.
    console.clear();

// the function will stop.
    return false;
}

// if its true function will log delet .
console.log("delet");

}

Omar bakhsh
quelle
0

Ich bevorzuge die Nutzung der node.isConnectedEigenschaft ( MDN besuchen ).

Hinweis: Dies gibt true zurück, wenn das Element auch an einen ShadowRoot angehängt wird, was möglicherweise nicht jedermanns gewünschtes Verhalten ist.

Beispiel:

const element = document.createElement('div');
console.log(element.isConnected); // Returns false
document.body.append(element);
console.log(element.isConnected); // Returns true
Robbendebiene
quelle