Разница между DOM parentNode и parentElement

501

Может кто-нибудь объяснить мне как можно проще, в чем разница между классическим DOM parentNode и недавно представленным в Firefox 9 parentElement?

shabunc
источник
4
parentNode кажется стандартным DOM, поэтому безопаснее всегда использовать его вместо parentElement.
TMS
5
@TMS w3school не является авторитетом: w3fools.com
Гийом Массе

Ответы:

487

parentElement является новым для Firefox 9 и DOM4, но он присутствовал во всех других основных браузерах целую вечность.

В большинстве случаев это так же, как parentNode. Единственная разница возникает, когда узел parentNodeне является элементом. Если так, то parentElementесть null.

Например:

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

Так как <html>элемент ( document.documentElement) не имеет родителя, который является элементом, parentElementесть null. (Существуют и другие, более маловероятные случаи, когда они parentElementмогут быть null, но вы, вероятно, никогда их не встретите.)

lonesomeday
источник
162
Другими словами, это совершенно бессмысленно 99,9999999999999% времени. Чья это была идея?
Niet the Dark Absol
25
Оригинал parentElementбыл собственностью IE; Я считаю, что другие браузеры в то время (например, Netscape) поддерживали, parentNodeно нет parentElement. (Очевидно, учитывая то, что я упомянул Netscape, я говорю об обратном пути к IE5 и более ранним версиям ...)
nnnnnn
9
@ lonesomeday вы забылиdocumentfragment.firstChild.parentElement === null
Raynos
7
@Raynos Это было именно то обстоятельство, которое я имел в виду с последним предложением моего ответа ...
одинокий день
17
Как я только что обнаружил, для элемента SVG (например, circleвнутри a g) в IE parentElementон будет неопределенным и parentNodeбудет тем, что вы ищете. :(
Джейсон Уолтон
94

В Internet Explorer parentElementне определено для элементов SVG, тогда parentNodeкак определено.

speedplane
источник
10
честно говоря, я думаю, что это скорее комментарий, а не ответ.
Шабун
39
Возможно, но это причина, по которой я ударился головой о стол в течение часа или более, пока не понял этого. Я подозреваю, что многие другие приходят на эту страницу после того же удара головой.
скоростной самолет
3
@speedplane Рада, что это ответ, так как это не имеет никакого логического смысла и заставило меня
суперфонический
1
Это также не определено для узлов комментариев. В Chrome я с радостью получил родительский комментарий, но в IE он не был определен.
Simon_Weaver
Я не мог найти источник для этого. хорошо известно, parentElementчто не внедряется для Node( developer.mozilla.org/en-US/docs/Web/API/Node/… ), но для SVGElement? Я также не мог воспроизвести это document.createElement('svg').parentElementв IE 11.737.17763.0. Это было возможно исправлено в это время?
эпсилон
14

Используйте, .parentElementи вы не ошибетесь, если не используете фрагменты документа.

Если вы используете фрагменты документа, то вам необходимо .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>


По- видимому, <html>«S .parentNodeссылки на документ . Это следует рассматривать как этап принятия решения, поскольку документы не являются узлами, поскольку узлы определены как содержащиеся в документах, а документы не могут содержаться в документах.

Pacerier
источник
6

Как и в случае с nextSibling и nextElementSibling , просто запомните, что свойства с именем «element» всегда возвращают Elementили null. Свойства без могут возвращать любой другой вид узла.

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
Buksy
источник
1
да, но в отличие от текстовых узлов или узлов комментариев не может быть родительским.
Jasen
0

Есть еще одно отличие, но только в Internet Explorer. Это происходит, когда вы смешиваете HTML и SVG. если родитель является «другим» из этих двух, то .parentNode дает родителя, в то время как .parentElement дает неопределенное.

mathheadinclouds
источник
1
Я думаю, что undefinedнет null.
Брайан Ди Пальма