2011-12-31 2 views
281

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

+0

http://stackoverflow.com/questions/2899196/what-is-this-parentelement –

+0

https://bugzilla.mozilla.org/show_bug.cgi?id=685798 –

+3

[ParentNode] (HTTP: // WWW .w3schools.com/dom/prop_node_parentnode.asp) кажется стандартом DOM, поэтому безопаснее всегда использовать его вместо parentElement. – TMS

ответ

286

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 

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

+85

Другими словами, это совершенно бессмысленно 99.999999999999% времени. Чья это была идея? –

+19

Исходный ['parentElement'] (http://msdn.microsoft.com/en-us/library/ms534327 (v = vs.85) .aspx) был запатентованной IE-темой; Я считаю, что другие браузеры в то время (например, Netscape) поддерживали «parentNode», но не «parentElement». (Очевидно, учитывая, что я упомянул Netscape, я говорю об обратном пути к IE5 и ранее ...) – nnnnnn

+0

@nnnnnn Хорошее знание: спасибо. – lonesomeday

5

Edit:Некоторые это неправильно. См комментарии подробности ниже

Все Element объекты также Node объекты (поскольку Element является потомком Node). Но есть Node, который не является Element ... document объект. Таким образом, ваш элемент <html> имеет родительский узел (document), но он не имеет родительского элемента.

Причина, по которой есть потребность в parentElement вместо parentNode потому, что HTML5 не строго требует <html> элемента, так что почти любой элемент может иметь родительский узел фактически без родительского элемента. Так что, если мой HTML страница выглядит следующим образом:

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

Тогда title, header, #body и footer элементы будут иметь свои parentNodedocument, как, но их parentElement будет нулевым. Только тег p будет иметь parentElement, который равен #body. (Обратите внимание, что я бы не советовал это как структура страницы ... прилипают к чему-то более традиционным.)

Вы можете повторить его с чем-то вроде этого:

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

* "потому что , HTML5 строго не требует элемента '' * Не верно, вы неверно истолковали спецификацию HTML5. Тег 'html' ** ** является необязательным, ** ** не является **, он всегда существует, тег подразумевается или явно предоставляется. [Подробности в Разделе 8 спецификации] (http://www.w3.org/TR/html5/syntax.html#optional-tags). –

+1

@ Натан Т.J. прав. Если вы на самом деле посмотрите на свою разметку, используя что-то вроде http://software.hixie.ch/utilities/js/live-dom-viewer/, и вы увидите, что в этом случае синтаксический анализатор введет '' и' 'элементов. Вы можете создавать ситуации, когда какой-то случайный тег, который не является «», является дочерним элементом документа но вы должны сделать это со сценарием (в HTML-документах; для случайного XML это не так), и это требует некоторой работы. –

+3

А, я вижу. Да, я неправильно интерпретировал, прочитав этот бит давно. –

46

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

+7

честно, я думаю, что это скорее комментарий, чем ответ. – shabunc

+19

Возможно, но это причина, по которой я ударил головой о стол в течение часа или больше, пока не понял. Я подозреваю, что многие другие приходят на эту страницу после аналогичного удара головой. – speedplane

+2

@speedplane Рад, что это ответ, так как это не имеет никакого логического смысла, и я сильно зашел в тупик ... – superphonic

1

Как и с nextSibling and nextElementSibling, просто помните, что свойства с «элементом» в их имени всегда возвращаются 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 
+0

да, но в отличие от следующего текста или комментариев узлы не могут быть родителями. – Jasen

2

Использование .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 ссылки к Document. Это следует рассматривать как факс решения, поскольку документы не являются узлами, поскольку узлы определены, которые могут быть скреплены документами и документами, которые не могут быть скреплены документами.

Смежные вопросы