Come posso verificare se esiste un elemento nel DOM visibile?


423

Come testare l'esistenza di un elemento senza l'uso del getElementByIdmetodo?

Ho creato una demo live per riferimento. Stamperò anche qui il codice:

<!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>

Fondamentalmente il codice sopra mostra un elemento che viene archiviato in una variabile e quindi rimosso dal DOM. Anche se l'elemento è stato rimosso dal DOM, la variabile mantiene l'elemento com'era quando è stato dichiarato per la prima volta. In altre parole, non è un riferimento attivo all'elemento stesso, ma piuttosto una replica. Di conseguenza, la verifica dell'esistenza del valore della variabile (l'elemento) fornirà un risultato imprevisto.

La isNullfunzione è il mio tentativo di verificare l'esistenza di elementi da una variabile e funziona, ma vorrei sapere se esiste un modo più semplice per ottenere lo stesso risultato.

PS: Sono anche interessato al motivo per cui le variabili JavaScript si comportano in questo modo se qualcuno conosce alcuni buoni articoli relativi all'argomento.


18
In realtà è un riferimento live all'elemento stesso, non è più in un documento. Tale funzionalità è necessaria perché è possibile effettivamente estrarre un elemento dal DOM e quindi reinserirlo in un secondo momento con tutti i gestori di eventi / ecc. Ancora associati. E perché le variabili JS si comportano così? Perché sarebbe incredibilmente fastidioso se non lo facessero. JS elimina le variabili solo quando non hai più NESSUN riferimento ad esse. La lingua non ha modo di sapere quali riferimenti ritieni importanti e quali ritieni inutili.
Mark Kahn,

@cwolves Interessante. L'ho incontrato molte volte prima e non ci ho mai pensato molto. In effetti, nel mio progetto attuale, sto salvando elementi in un array prima di apportare eventuali modifiche, nel caso in cui volessi annullare le modifiche.
Justin Bull,

1
La raccolta dei rifiuti viene eseguita di volta in volta ed elimina tutto ciò che pensa di poter fare. Sembra piuttosto scadente nella maggior parte dei browser, ma sta migliorando quando gli sviluppatori si rendono conto che alcuni browser funzionano per giorni o settimane tra i riavvii, quindi una buona garbage collection è vitale per le prestazioni del browser. Gli sviluppatori Web possono aiutare eliminando le proprietà (e quindi i riferimenti alle cose in memoria) che non sono più necessarie.
RobG

2
@JustinBull stai attento con l'archiviazione di copie degli elementi da ripristinare. Quando si memorizza un elemento DOM in un array, viene memorizzato un riferimento all'elemento DOM, non una copia, quindi le modifiche apportate all'elemento DOM verranno riflesse quando si fa riferimento all'elemento dell'array. Questo è il caso di tutti gli oggetti in JavaScript (variabili di tipo 'oggetto').
Anthony DiSanti,

Risposte:


545

Sembra che alcune persone stiano atterrando qui e vogliono semplicemente sapere se esiste un elemento (un po 'diverso dalla domanda originale).

È semplice come utilizzare uno dei metodi di selezione del browser e verificarlo per un valore veritiero (generalmente).

Ad esempio, se il mio elemento avesse un idof "find-me", potrei semplicemente usare ...

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

Questo è specificato per restituire un riferimento all'elemento o null. Se devi avere un valore booleano, lancia semplicemente un !!prima della chiamata al metodo.

Inoltre, puoi utilizzare alcuni dei molti altri metodi esistenti per trovare elementi, come (tutti viventi document):

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

Alcuni di questi metodi restituiscono a NodeList, quindi assicurati di controllarne la lengthproprietà, perché a NodeListè un oggetto e quindi veritiero .


Per determinare effettivamente se esiste un elemento come parte del DOM visibile (come la domanda originariamente posta), Csuwldcat offre una soluzione migliore rispetto al rotolamento del proprio (come conteneva questa risposta). Cioè, per utilizzare ilcontains() metodo su elementi DOM.

Potresti usarlo così ...

document.body.contains(someReferenceToADomElement);

1
Esattamente quello che stavo cercando! Quindi ovviamente lol, perché non ci ho pensato. Inoltre, conosci qualche buon articolo che spiega perché le variabili si comportano così?
Justin Bull,

3
Ancora più breve:var elementInDom = function( el ) { while ( el = el.parentNode ) if ( el === document ) return true; return false; }
bennedich,

2
@ButtleButkus Leggi la domanda reale. Tale soluzione si è utilizzato non ha senso come getElementById() sarà restituire un riferimento a un elemento DOM o null, quindi, usando typeof(in particolare sul RHS) è sbagliato (se non sono stati definiti, la condizione LHS getterebbe una ReferenceError).
alex,

2
C'è qualche motivo per usarlo su ciò che è stato pubblicato di seguito: document.body.contains()quale sembra avere un ottimo supporto per il browser?
schiaccia

1
@Jonz Rimossa la vecchia parte della risposta, non dimenticare di andare a votare csuwldcat
alex

310

Utilizzare getElementById()se è disponibile.

Inoltre, ecco un modo semplice per farlo con jQuery:

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

E se non puoi utilizzare librerie di terze parti, ti basterà attenersi a JavaScript di base:

var element =  document.getElementById('elementId');
if (typeof(element) != 'undefined' && element != null)
{
  // Exists.
}

2
Per il progetto a cui sto lavorando, non sono in grado di utilizzare una libreria. Solo buon codice raw fashion. Sono a conoscenza del metodo jQuery, ma non funziona su elementi non racchiusi nel contenitore jQuery. Ad esempio, $('#elementId')[0].lengthnon produrrebbe lo stesso risultato.
Justin Bull,

8
C'è qualche buona ragione per un'istruzione if così complicata nel secondo esempio di codice? Perché non semplicemente if (element) {}? Quando l'elemento è indefinito o nullo, questa espressione è falsa. Se element è un elemento DOM allora l'espressione è vera.
kayahr,

2
@kayahr È troppo complicato. getElementById()viene specificato per restituire nullse non trova l'elemento, quindi è necessario verificare un valore restituito sinceramente .
alex

5
Penso che sia solo buon senso.
Kon

8
getElementByIdnon dovrebbe mai tornare undefined. In ogni caso, il element != nullcontrollo lo prenderebbe.

191

Utilizzando l' API DOM Node.contains , è possibile verificare abbastanza facilmente la presenza di qualsiasi elemento nella pagina (attualmente nel DOM):

document.body.contains(YOUR_ELEMENT_HERE);

NOTA CROSS-BROWSER : l' documentoggetto in Internet Explorer non ha un contains()metodo: per garantire la compatibilità tra browser, utilizzare document.body.contains()invece.


4
Questa sembra la risposta definitiva a questo problema ... e il suo supporto, se si deve credere che MDN sia abbastanza buono.
schiaccia

2
Questa è la risposta migliore Nota che solo il controllo document.contains()dovrebbe essere sufficiente.
alex,

@csuwldcat Ha funzionato per me, almeno in Chrome con document.contains(document.documentElement). documentha Nodesulla sua catena di prototipi, per quanto ne so ( document-> HTMLDocument-> Document-> Node)
alex

4
Questa è davvero la risposta migliore: - è uno standard web - è molto ben supportato (un po 'sorprendentemente non appare in Firefox fino alla versione 9, suppongo perché era una funzione non standard inventata in IE che non lo era standardizzato fino a dopo) - deve essere il più veloce perché utilizza una singola chiamata a un'API nativa
Jon z

2
@LeeSaxon La sintassi è document.body.contains([selector]), cioèdocument.body.contains(document.getElementById('div')
iglesiasedd,

67

Faccio semplicemente:

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

Funziona per me e non ha ancora avuto problemi con ...


1
Questo non ha nulla a che fare con la domanda originale. L'OP vuole sapere se un riferimento a un elemento DOM fa parte o meno del DOM visibile.
alex

16
Mi ha aiutato però. Stavo cercando il semplice test dell'esistenza degli elementi; questo ha funzionato. Grazie.
Khaverim,

1
Questa risposta funziona bene, ma solo quando l'elemento ha un id. La soluzione migliore che risponde alla domanda Come verificare se esiste un elemento nel DOM visibile? con qualsiasi elemento, anche gli elementi senza ids devono fare document.body.contains(element).
Edward,

@Edward Questo è qualcosa di completamente diverso dacontains()
alex

Capisco quello. Stavo solo suggerendo nel mio commento che altre risposte sono migliori e più adatte alla domanda.
Edward,

11

Si può semplicemente verificare se la proprietà parentNode è null.

Questo è,

if(!myElement.parentNode)
{
    // The node is NOT in the DOM
}
else
{
    // The element is in the DOM
}

So che questa è una vecchia domanda, ma questa risposta è esattamente il tipo di elegante semplice soluzione alla domanda che stavo cercando.
poby,

11
@poby: potrebbe sembrare elegante ma non sta davvero facendo ciò che è stato richiesto. Controlla solo se l'elemento ha un elemento padre. Ciò non implica che l'elemento sia nel DOM visibile perché forse l'elemento genitore non è collegato ad esso.
Kayahr,

Bisognerebbe passare attraverso tutti i genitori dei genitori per scoprire se l'ultimo è un documento. L'altro problema è che potrebbe essere al di fuori dell'intervallo visibile o essere coperto o non essere visibile a causa di molte altre ragioni.
Arek Bal,

Un elemento può anche avere un parentNode solo in virtù dell'aggiunta a un frammento di documento.

11

Dalla rete di sviluppatori Mozilla :

Questa funzione controlla se un elemento si trova nel corpo della pagina. Dato che contiene () è inclusivo e determinare se il corpo contiene se stesso non è l'intenzione di isInPage, questo caso restituisce esplicitamente falso.

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

nodo è il nodo che vogliamo controllare in <body>.


+1, funziona anche con nodi di testo (arbitrari) (o nodi di commento)?
Nikos M.,

@NikosM. Dovrebbe funzionare con qualsiasi tag html ma non l'ho provato.
Ekramul Hoque,

4
Non dovrebbe falseessere true?
Marc-André Lafortune,

Se l' nodeIS è il document.body, sicuramente il metodo dovrebbe tornare true? Cioè,return (node === document.body) || document.body.contains(node);
daiscog,

7

La soluzione più semplice è controllare la proprietà baseURI , che viene impostata solo quando l'elemento è inserito nel DOM e, quando viene rimosso, ritorna a una stringa vuota.

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>


5
Non sapevo nemmeno che esistesse la proprietà baseURI sui nodi DOM. Quello che mi piace di questo approccio è che usa una proprietà dell'elemento stesso, il che presumibilmente significa che funzionerebbe anche se l'elemento si trova in un documento diverso (ad esempio un iframe). Quello che non mi piace è che non sembra funzionare al di fuori di Webkit.
DoctorDestructo,

Attenzione in quanto questo getterà il seguente errore se l'elemento non è nel documento: Cannot read property 'baseURI' of null. Esempio:console.log(document.querySelector('aside').baseURI)
Ian Davis,

Questo metodo non può essere utilizzato in quanto stampa sempre la stessa stringa di adesso.
Kagami Sascha Rosylight,

4

soluzione jQuery:

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

Questo ha funzionato per me utilizzando jQuery e non è stato necessario $('#elementId')[0]utilizzarlo.


Perché $('#elementId')[0]qualcosa da evitare?
alex

Da tempo ho risposto a questo, quindi, usando $ ('# elementId') [0] credo che indichi sempre che il valore sarà al 0 ° indice. In questo modo si controlla sempre il primo elemento occorrente. Che cosa c'erano più caselle di controllo con lo stesso nome, quindi come un pulsante di opzione. Quella volta la lunghezza sarà utile.
Code Buster

3

La soluzione di csuwldcat sembra essere la migliore del gruppo, ma è necessaria una leggera modifica per farlo funzionare correttamente con un elemento che si trova in un documento diverso rispetto al codice JavaScript in esecuzione, come un iframe:

YOUR_ELEMENT.ownerDocument.body.contains(YOUR_ELEMENT);

Nota l'uso della ownerDocumentproprietà dell'elemento , al contrario di un semplice vecchiodocument (che può o meno riferirsi al documento proprietario dell'elemento).

torazaburo ha pubblicato un metodo ancora più semplice che funziona anche con elementi non locali, ma sfortunatamente utilizza la baseURIproprietà, che al momento non è uniformemente implementata sui browser (potrei farlo funzionare solo in quelli basati su WebKit ). Non sono riuscito a trovare nessun altro elemento o proprietà del nodo che potesse essere usato in modo simile, quindi per il momento penso che la soluzione di cui sopra sia la migliore possibile.


3

Invece di iterare i genitori, puoi semplicemente ottenere il rettangolo di delimitazione che è tutto zeri quando l'elemento è staccato dal DOM:

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

Se si desidera gestire il caso limite di un elemento larghezza e altezza zero in alto a zero e zero a sinistra, è possibile ricontrollare eseguendo l'iterazione dei genitori fino a quando 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;
}


3

Un modo semplice per verificare se esiste un elemento può essere fatto tramite il codice di una riga di jQuery.

Ecco il codice qui sotto:

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


2

Questo codice funziona per me e non ho avuto problemi con esso.


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

1

Puoi anche usare jQuery.contains, che controlla se un elemento è un discendente di un altro elemento. Sono passato documentcome elemento principale da cercare perché tutti gli elementi presenti nella pagina DOM sono discendenti di document.

jQuery.contains( document, YOUR_ELEMENT)

1

Controlla se l'elemento è figlio di <html>via Node::contains():

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

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

Ho coperto questo e altro in is-dom-distaccato .


1

Una soluzione semplice con jQuery:

$('body').find(yourElement)[0] != null

2
... oppure$(document).find(yourElement).length !== 0
Grinn,

1
Questo lo sfrutta null == undefined. Il vero valore restituito sarebbe undefined. Confrontarlo con nullè un po 'strano.
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;
}

In tutto cosa? Tutti i casi?
Peter Mortensen,

1
  • Se un elemento è in DOM , anche i suoi genitori dovrebbero esserlo
  • E l'ultimo nonno dovrebbe essere il document

Quindi, per verificare che ci limitiamo a scorrere verso l'elemento parentNode sull'albero fino a raggiungere l'ultimo nonno

Usa questo:

/**
 * @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;
};

2
Questa potrebbe essere la risposta migliore in quanto non provoca alcun nuovo rendering nel DOM.
Steven Vachon,

Una spiegazione sarebbe in ordine (rispondere modificando la risposta , non qui nei commenti).
Peter Mortensen,

0

Mi è piaciuto questo approccio:

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

if (elem)
    do this
else
    do that

Anche

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

if (elem)
    do this
else
    do that

1
Perché non solo !!se vuoi un booleano?
alex,

Quindi, se l'elemento non ha un id, allora è considerato non nel DOM? Direi che è sbagliato.
Steven Vachon,

0

Utilizzare querySelectorAllcon forEach,

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

come l'opposto di:

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

0

Prova quanto segue. È la soluzione più affidabile:

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

Per esempio,

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'


0

Tutti gli elementi esistenti hanno parentElement impostato, tranne l'elemento HTML!

function elExists (e) { 
    return (e.nodeName === 'HTML' || e.parentElement !== null);
};

È sempre "HTML" ? Potrebbe essere "html" ?
Peter Mortensen,

x.tagName o x.nodeName sempre in maiuscolo, non importa come lo scrivi nel tuo codice
Giona

0

questa condizione pulcino tutti i casi.

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");

}


0

Preferisco usare la node.isConnectedproprietà ( Visita MDN ).

Nota: questo tornerà vero se l'elemento viene aggiunto anche a ShadowRoot, che potrebbe non essere il comportamento desiderato da tutti.

Esempio:

const element = document.createElement('div');
console.log(element.isConnected); // Returns false
document.body.append(element);
console.log(element.isConnected); // Returns true
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.