Comment puis-je vérifier si un élément existe dans le DOM visible?

423

Comment testez-vous l'existence d'un élément sans utiliser la getElementByIdméthode?

J'ai mis en place une démo en direct pour référence. Je vais également imprimer le code ici également:

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

Fondamentalement, le code ci-dessus montre qu'un élément est stocké dans une variable, puis supprimé du DOM. Même si l'élément a été supprimé du DOM, la variable conserve l'élément tel qu'il était lors de sa première déclaration. En d'autres termes, ce n'est pas une référence en direct à l'élément lui-même, mais plutôt une réplique. Par conséquent, la vérification de l'existence de la valeur de la variable (l'élément) fournira un résultat inattendu.

La isNullfonction est ma tentative de vérifier l'existence d'un élément à partir d'une variable, et cela fonctionne, mais je voudrais savoir s'il existe un moyen plus simple d'obtenir le même résultat.

PS: Je m'intéresse également aux raisons pour lesquelles les variables JavaScript se comportent comme cela si quelqu'un connaît de bons articles liés au sujet.

Justin Bull
la source
18
En fait, c'est une référence en direct à l'élément lui-même, il n'est tout simplement plus dans un document. Cette fonctionnalité est requise car vous pouvez réellement extraire un élément du DOM, puis le réinstaller plus tard avec tous les gestionnaires d'événements / etc encore attachés. Quant à savoir pourquoi les variables JS agissent comme ça? Parce que ce serait incroyablement ennuyeux s'ils ne le faisaient pas. JS supprime uniquement les variables lorsque vous n'avez plus aucune référence à celles-ci. Le langage n'a aucun moyen de savoir quelles références vous jugez importantes et lesquelles vous pensez ne valent rien.
Mark Kahn
@cwolves Intéressant. J'en ai rencontré plusieurs fois auparavant et je n'y ai jamais vraiment pensé. En fait, dans mon projet actuel, j'enregistre des éléments dans un tableau avant d'y apporter des modifications, juste au cas où je souhaiterais annuler les modifications.
Justin Bull
1
La collecte des ordures s'exécute de temps en temps et supprime tout ce qu'elle pense pouvoir. Cela semble assez moche dans la plupart des navigateurs, mais s'améliore à mesure que les développeurs réalisent que certains navigateurs fonctionnent pendant des jours ou des semaines entre les redémarrages, donc une bonne récupération de place est vitale pour les performances du navigateur. Les développeurs Web peuvent aider en supprimant les propriétés (et donc les références aux éléments en mémoire) qui ne sont plus nécessaires.
RobG
2
@JustinBull soyez prudent avec le stockage de copies des éléments à restaurer. Lors du stockage d'un élément DOM dans un tableau, une référence à l'élément DOM est stockée, pas une copie, donc les modifications apportées à l'élément DOM seront reflétées lors du référencement de l'élément du tableau. C'est le cas de tous les objets en javascript (variables de type 'objet').
Anthony DiSanti

Réponses:

545

Il semble que certaines personnes atterrissent ici et veulent simplement savoir si un élément existe (un peu différent de la question d'origine).

C'est aussi simple que d'utiliser l'une des méthodes de sélection du navigateur et de vérifier sa véracité valeur ( en général).

Par exemple, si mon élément avait un idof "find-me", je pourrais simplement utiliser ...

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

Ceci est spécifié pour renvoyer une référence à l'élément ou null. Si vous devez avoir une valeur booléenne, lancez simplement un!! avant l'appel de méthode.

En outre, vous pouvez utiliser certaines des nombreuses autres méthodes qui existent pour trouver des éléments, tels que (tous vivant document):

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

Certaines de ces méthodes renvoient a NodeList, alors assurez-vous de vérifier sa lengthpropriété, car a NodeListest un objet, et donc véridique .


Pour déterminer réellement si un élément existe dans le DOM visible (comme la question posée à l'origine), Csuwldcat fournit une meilleure solution que de rouler le vôtre (comme cette réponse contenait autrefois). Autrement dit, pour utiliser lecontains() méthode sur les éléments DOM.

Vous pouvez l'utiliser comme ça ...

document.body.contains(someReferenceToADomElement);
alex
la source
1
Exactement ce que je cherchais! Alors évidemment lol, pourquoi n'y ai-je pas pensé. De plus, connaissez-vous de bons articles qui expliquent pourquoi les variables agissent ainsi?
Justin Bull
3
Encore plus court:var elementInDom = function( el ) { while ( el = el.parentNode ) if ( el === document ) return true; return false; }
bennedich
2
@ButtleButkus Lisez la vraie question. Cette solution que vous avez utilisée n'a pas de sens car getElementById() elle renverra une référence à un élément DOM ou null, par conséquent, l'utilisation typeof(en particulier sur le RHS) est incorrecte (si elle n'était pas définie, la condition LHS renverrait a ReferenceError).
alex
2
Y a-t-il une raison de l'utiliser sur ce qui a été publié ci-dessous: document.body.contains()qui semble avoir un très bon support pour le navigateur?
écraser le
1
@Jonz Suppression de l' ancienne partie de réponse, n'oubliez pas d'aller voter csuwldcat
alex
310

À utiliser getElementById()s'il est disponible.

En outre, voici un moyen simple de le faire avec jQuery:

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

Et si vous ne pouvez pas utiliser de bibliothèques tierces, respectez simplement le code JavaScript de base:

var element =  document.getElementById('elementId');
if (typeof(element) != 'undefined' && element != null)
{
  // Exists.
}
Kon
la source
2
Pour le projet sur lequel je travaille, je ne peux pas utiliser de bibliothèque. Good-ol 'fashion raw code only. Je connais cette méthode jQuery, mais elle ne fonctionne pas sur les éléments non enveloppés dans le conteneur jQuery. Par exemple, $('#elementId')[0].lengthne produirait pas le même résultat.
Justin Bull
8
Y a-t-il une bonne raison pour une instruction if si compliquée dans le deuxième exemple de code? Pourquoi pas simplement if (element) {}? Lorsque l'élément est indéfini ou nul, cette expression est fausse. Si l'élément est un élément DOM, l'expression est vraie.
kayahr
2
@kayahr C'est beaucoup trop compliqué. getElementById()est spécifié pour retourner nulls'il n'a pas trouvé l'élément, donc il suffit de vérifier une valeur retournée véridique .
alex
5
Je pense que c'est juste du bon sens.
Kon
8
getElementByIdne devrait jamais revenir undefined. Dans tous les cas, le element != nullchèque reprendrait cela.
191

En utilisant l' API DOM Node.contains , vous pouvez vérifier la présence de tout élément dans la page (actuellement dans le DOM) assez facilement:

document.body.contains(YOUR_ELEMENT_HERE);

CROSS-BROWSER REMARQUE : l' documentobjet dans Internet Explorer n'a pas de contains()méthode - pour assurer la compatibilité entre les navigateurs, utilisez document.body.contains()plutôt.

csuwldcat
la source
4
Cela semble être la réponse ultime à ce problème ... et son soutien, si l'on en croit MDN, est assez bon.
écraser le
2
C'est la meilleure réponse. Notez que la simple vérification document.contains()devrait suffire.
alex
@csuwldcat Cela a fonctionné pour moi, au moins dans Chrome avec document.contains(document.documentElement). documenta Nodesur sa chaîne prototype, pour autant que je sache ( document-> HTMLDocument-> Document-> Node)
alex
4
C'est en effet la meilleure réponse: - c'est un standard Web - il est très bien pris en charge (quelque peu surprenant, il n'apparaît dans Firefox qu'à partir de la version 9, je suppose que c'était une fonction non standard inventée dans IE qui n'était pas standardisé jusqu'à plus tard) - il doit être le plus rapide car il utilise un seul appel vers une API native
Jon z
2
@LeeSaxon La syntaxe est document.body.contains([selector]), c'estdocument.body.contains(document.getElementById('div')
iglesiasedd
68

Je fais simplement:

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

Cela fonctionne pour moi et je n'ai eu aucun problème avec ça encore ...

Anomalie
la source
1
Cela n'a cependant rien à voir avec la question d'origine. L'OP veut savoir si une référence à un élément DOM fait partie du DOM visible ou non.
alex
16
Mais m'a aidé. Je cherchais le test simple de l'existence d'un élément; cela a fonctionné. Merci.
khaverim
1
Cette réponse fonctionne bien, mais uniquement lorsque l'élément a un id. La meilleure solution qui répond à la question Comment vérifier si l'élément existe dans le DOM visible? avec n'importe quel élément, même les éléments sans ids est à faire document.body.contains(element).
Edward
@Edward C'est quelque chose de complètement différent decontains()
alex
Je comprends ça. Je disais simplement dans mon commentaire que d'autres réponses sont meilleures et mieux adaptées à la question.
Edward
11

Vous pouvez simplement vérifier si la propriété parentNode est nulle.

C'est,

if(!myElement.parentNode)
{
    // The node is NOT in the DOM
}
else
{
    // The element is in the DOM
}
mikechambers
la source
Je sais que c'est une vieille question mais cette réponse est exactement le genre de solution simple et élégante à la question que je cherchais.
poby
11
@poby: Cela peut sembler élégant, mais il ne fait pas vraiment ce qui a été demandé. Il vérifie uniquement si l'élément a un élément parent. Cela n'implique pas que l'élément se trouve dans le DOM visible car peut-être que l'élément parent n'y est pas connecté.
kayahr
Il faudrait passer par tous les parents des parents pour savoir si le dernier est un document. L'autre problème est qu'il pourrait toujours être hors de portée visible ou être couvert ou ne pas être visible pour de nombreuses autres raisons.
Arek Bal
Un élément ne peut également avoir un parentNode qu'en raison de son ajout à un fragment de document.
11

De Mozilla Developer Network :

Cette fonction vérifie si un élément se trouve dans le corps de la page. Comme contains () est inclusif et déterminer si le corps se contient n'est pas l'intention d'isInPage, ce cas renvoie explicitement false.

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

nœud est le nœud que nous voulons vérifier dans le <body>.

Ekramul Hoque
la source
+1, cela fonctionne-t-il également pour les nœuds de texte (ou les commentaires) (arbitraires)?
Nikos M.
@NikosM. Cela devrait fonctionner dans n'importe quelle balise html mais je ne l'ai pas testé.
Ekramul Hoque du
4
Ne devrait-il pas en falseêtre ainsi true?
Marc-André Lafortune
Si l' nodeIS le document.body, sûrement la méthode doit revenir true? C'est à dire,return (node === document.body) || document.body.contains(node);
daiscog
7

La solution la plus simple consiste à vérifier la propriété baseURI , qui n'est définie que lorsque l'élément est inséré dans le DOM, et elle revient à une chaîne vide lorsqu'elle est supprimée.

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
la source
5
Je ne savais même pas qu'il y avait une propriété baseURI sur les nœuds DOM. Ce que j'aime dans cette approche, c'est qu'elle utilise une propriété de l'élément lui-même, ce qui signifie probablement que cela fonctionnerait même si l'élément se trouve dans un document différent (par exemple, un iframe). Ce que je n'aime pas, c'est qu'il ne semble pas fonctionner en dehors de Webkit.
DoctorDestructo
Attention , car cela jette l'erreur suivante si l'élément est pas dans le document: Cannot read property 'baseURI' of null. Exemple:console.log(document.querySelector('aside').baseURI)
Ian Davis
Cette méthode ne peut pas être utilisée car elle affiche toujours la même chaîne à partir de maintenant.
Kagami Sascha Rosylight
4

Solution jQuery:

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

Cela a fonctionné pour moi en utilisant jQuery et n'a pas nécessité $('#elementId')[0]d'être utilisé.

Code Buster
la source
Pourquoi $('#elementId')[0]faut-il éviter quelque chose?
alex
Cela fait longtemps que j'ai répondu à cela, Donc, en utilisant $ ('# elementId') [0] Je crois que vous indiquez toujours que la valeur sera au 0ème index. De cette façon, vous vérifiez toujours le 1er élément apparaissant. Qu'est-ce qu'il y avait plusieurs cases à cocher avec le même nom, donc comme un bouton radio. Cette fois, la longueur sera utile.
Code Buster
3

La solution de csuwldcat semble être la meilleure du lot, mais une légère modification est nécessaire pour qu'elle fonctionne correctement avec un élément qui se trouve dans un document différent de celui dans lequel le code JavaScript s'exécute, tel qu'un iframe:

YOUR_ELEMENT.ownerDocument.body.contains(YOUR_ELEMENT);

Notez l'utilisation de la ownerDocumentpropriété de l'élément , par opposition à tout simplement anciendocument (qui peut ou non faire référence au document du propriétaire de l'élément).

torazaburo a affiché une méthode encore plus simple fonctionne aussi que des éléments non locaux, mais malheureusement, il utilise la baseURIpropriété, qui n'est pas appliquée uniformément à travers les navigateurs à ce moment (je ne pouvais le faire fonctionner dans le WebKit ceux à base). Je n'ai trouvé aucun autre élément ou propriété de nœud qui pourrait être utilisé de la même manière, donc je pense que pour l'instant la solution ci-dessus est aussi bonne que possible.

DocteurDestructo
la source
3

Au lieu d'itérer les parents, vous pouvez simplement obtenir le rectangle englobant qui est tout à zéro lorsque l'élément est détaché du DOM:

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

Si vous souhaitez gérer le cas de bord d'un élément de largeur et de hauteur nul en haut en haut et zéro à gauche, vous pouvez vérifier deux fois en itérant les parents jusqu'à ce que 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
la source
Cela provoque une réorganisation: gist.github.com/paulirish/5d52fb081b3570c81e3a#box-metrics
Steven Vachon
3

Un moyen simple de vérifier si un élément existe peut être fait via le code à une ligne de jQuery.

Voici le code ci-dessous:

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

Une autre option est element.closest :

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

Ce code fonctionne pour moi et je n'ai eu aucun problème avec lui.


    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
la source
1

Vous pouvez également utiliser jQuery.contains, qui vérifie si un élément est un descendant d'un autre élément. Je suis passé en documenttant qu'élément parent à rechercher car tous les éléments qui existent sur la page DOM sont des descendants de document.

jQuery.contains( document, YOUR_ELEMENT)
nitinkhuranas
la source
1

Vérifiez si l'élément est un enfant de <html>via Node::contains():

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

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

J'ai couvert cela et plus dans is-dom-détaché .

Steven Vachon
la source
1

Une solution simple avec jQuery:

$('body').find(yourElement)[0] != null
mateusmaso
la source
2
... ou$(document).find(yourElement).length !== 0
Grinn
1
Cela exploite cela null == undefined. La vraie valeur retournée serait undefined. Le comparer nullest un peu bizarre.
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
la source
En tout quoi? Tous les cas?
Peter Mortensen
1
  • Si un élément est dans le DOM, ses parents doivent également être en
  • Et le dernier grand-parent devrait être le document

Donc, pour vérifier que nous bouclons simplement vers l' parentNodearbre de l'élément jusqu'à ce que nous atteignions le dernier grand-parent

Utilisez ceci:

/**
 * @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
la source
2
Cela pourrait être la meilleure réponse car elle ne provoque aucun re-rendu dans le DOM.
Steven Vachon
Une explication serait de mise (répondez en éditant votre réponse , pas ici dans les commentaires).
Peter Mortensen
0

J'ai aimé cette approche:

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

if (elem)
    do this
else
    do that

Aussi

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

if (elem)
    do this
else
    do that
Hugh
la source
1
Pourquoi pas !!si vous voulez un booléen?
alex
Donc, si l'élément n'a pas d'identifiant, alors il est considéré comme n'étant pas dans le DOM? Je dirais que c'est faux.
Steven Vachon
0

Utiliser querySelectorAllavec forEach,

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

comme l'opposé de:

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

Essayez ce qui suit. C'est la solution la plus fiable:

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

Par exemple,

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
la source
1
Cela provoque probablement une réorganisation: gist.github.com/paulirish/5d52fb081b3570c81e3a#getcomputedstyle
Steven Vachon
0

Tous les éléments existants ont parentElement défini, sauf l'élément HTML!

function elExists (e) { 
    return (e.nodeName === 'HTML' || e.parentElement !== null);
};
Jonas
la source
Est-ce toujours "HTML" ? Serait-ce "html" ?
Peter Mortensen
x.tagName ou x.nodeName toujours en majuscules, peu importe comment vous l'écrivez dans votre code
Jonah
0

cette condition poussin tous les cas.

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
la source
0

Je préfère utiliser la node.isConnectedpropriété ( visitez MDN ).

Remarque: Cela retournera vrai si l'élément est également ajouté à un ShadowRoot, ce qui pourrait ne pas être le comportement de tout le monde.

Exemple:

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