Difference between DOM parentNode and parentElement

Difference between DOM parentNode and parentElement

Can somebody in explain me in as simple as possible terms, what is the difference between classical DOM parentNode and newly introduced in Firefox 9 parentElement


Solution 1:

parentElement is new to Firefox 9 and to DOM4, but it has been present in all other major browsers for ages.

In most cases, it is the same as parentNode. The only difference comes when a node’s parentNode is not an element. If so, parentElement is null.

As an example:

document.body.parentNode; // the <html> element
document.body.parentElement; // the <html> element

document.documentElement.parentNode; // the document node
document.documentElement.parentElement; // null

(document.documentElement.parentNode === document);  // true
(document.documentElement.parentElement === document);  // false

Since the <html> element (document.documentElement) doesn’t have a parent that is an element, parentElement is null. (There are other, more unlikely, cases where parentElement could be null, but you’ll probably never come across them.)

Solution 2:

In Internet Explorer, parentElement is undefined for SVG elements, whereas parentNode is defined.

Solution 3:

Use .parentElement and you can’t go wrong as long as you aren’t using document fragments.

If you use document fragments, then you need .parentNode:

let div = document.createDocumentFragment().appendChild(document.createElement('div'));
div.parentElement // null
div.parentNode // document fragment


let div = document.getElementById('t').content.firstChild
div.parentElement // null
div.parentNode // document fragment
<template id="t"><div></div></template>

Apparently the <html>‘s .parentNode links to the Document. This should be considered a decision phail as documents aren’t nodes since nodes are defined to be containable by documents and documents can’t be contained by documents.

Solution 4:

Edit: Some of this is wrong. See comments below for details

All Element objects are also Node objects (because Element is a descendent of Node). But there is a Node which isn’t an Element… the document object. So your <html> element has a parent node (document) but it doesn’t have a parent element.

The reason that there’s a need for parentElement instead of parentNode is because, HTML5 doesn’t strictly require an <html> element, so almost any element can have a parent node without actually having a parent element. So if my HTML page looked like this:

<!doctype html>
<title>My page</title>
<header>This is my page</header>
<div id="body">
  <p>This is some text from my page</p>
  Copyright, me

Then the title, header, #body and footer elements would have their parentNode as document, but their parentElement would be null. Only the p tag would have a parentElement, which is #body. (Note that I wouldn’t advise this as a page structure… stick to something more traditional.)

You can replicate it with something like this:

if (myElement.parentNode instanceof Element) {
    myElement.parentElement = myElement.parentNode;
} else {
    myElement.parentElement = null;

Solution 5:

Just like with nextSibling and nextElementSibling, just remember that, properties with “element” in their name always returns Element or null. Properties without can return any other kind of node.

console.log(document.body.parentNode, "is body's parent node");    // returns <html>
console.log(document.body.parentElement, "is body's parent element"); // returns <html>

var html = document.body.parentElement;
console.log(html.parentNode, "is html's parent node"); // returns document
console.log(html.parentElement, "is html's parent element"); // returns null