ParentNode et ParentElement

On en apprend tous les jours, même après plus de quinze ans de dev web. Aujourd'hui, l'avantage de parentElement par rapport à parentNode.

J'ai toujours eu l'habitude d'utiliser parentNode. Pas une mauvaise habitude en soi mais elle a un certain inconvénient quand on écrit quelque chose du genre :

const getFooAscendant = function (element) {
    while (element.parentNode) {
        if (element.parentNode.classList.contains('foo')) {
            return element.parentNode;
        }
        element = element.parentNode;
    }
    return null;
}
Recherche d'un ascendant avec un certaine caractéristique.

Ce code plante si la condition de sortie de la boucle while n'est pas résolue. Pourquoi ? Parce que ParentNode remonte jusqu'à l'objet Document qui est une Node. Hors, l'API classList appartient à l'objet Element… Pour éviter ce problème, j'ajoute depuis des années un test pour savoir si la boucle ascendante est arrivée jusqu'au noeud body, auquel cas je l'arrête.

const getFooAscendant = function (element) {
    while (element.parentNode) {
        if (element.parentNode.classList.contains('foo')) {
            return element.parentNode;
        }
        if (element.parentNode === document.body) {
            return null;
        }
        element = element.parentNode;
    }
    return null;
}
Recherche d'un ascendant jusqu'à arriver au body.

Les habitudes ont la vie dures et je n'ai jamais vraiment cherché à trouver une alternative (si un code fonctionne, on n'y touche plus !). Pourtant, il suffit d'utiliser parentElement au lieu de parentNode et le problème est règlé :

const getFooAscendant = function (element) {
    while (element.parentElement) {
        if (element.parentElement.classList.contains('foo')) {
            return element.parentElement;
        }
        element = element.parentElement;
    }
    return null;
}
Recherche d'un ascendant Element avec un certaine caractéristique.

Voilà : c'était l’enfonçage de portes ouvertes du jour.