在javascript DOM中,类Attr扩展了nodeType==Node.ATTRIBUTE_Node的Node。这太棒了。Node.prototype具有parentNode属性,该属性是某种getter";获取parentNode";我无法检查(在Chrome上(车身的功能。但是对于Attr,parentNode总是返回null,并且也不能赋值。
我想知道为什么会这样?他们是否期望Attr对象在不同的节点之间被重用和共享?
这里我展示了一个Chrome控制台对话框:
$0
<section code="123" foo="bar">…</section>
$0.attributes[0]
code="123"
$0.attributes[0].parentNode
null
$0.attributes[0].parentNode = $0
<section code="123" foo="bar">…</section>
$0.attributes[0].parentNode
null
Object.defineProperty(Attr.prototype, 'parentNode', { writable: true, value: null });
Attr {…}
$0.attributes[0].parentNode
null
$0.attributes[0].parentNode = $0
<section code="123" foo="bar">…</section>
$0.attributes[0].parentNode
<section code="123" foo="bar">…</section>
现在属性是否被重用?
s = $0.cloneNode(false)
<section code="123" foo="bar"></section>
s.attributes[0] == $0.attributes[0]
false
s.attributes.removeNamedItem('code')
code="123"
s.attributes.removeNamedItem('foo')
foo="bar"
s
<section></section>
s.attributes.setNamedItem($0.attributes[0])
Uncaught DOMException: Failed to execute 'setNamedItem' on 'NamedNodeMap': The node provided is an attribute node that is already an attribute of another Element; attribute nodes must be explicitly cloned.
s.attributes.setNamedItem($0.attributes[0].cloneNode())
null
s
<section code="123"></section>
因此,很明显,Attr不应该在不同的元素之间共享。因此,我不明白为什么parentNode属性被决定为Attr节点保留不起作用?
我可能可以自己解决问题,用一个特定于Attr的属性覆盖Node属性,但为什么呢?
要知道一个用例是什么?那么,如何在javascript上实现XSLT呢?在XSLT中,您可以查询属性的父级,这通常非常重要。
根据规范:
注意:
CCD_ 1节点由于历史原因而参与树;它们从来没有(非null(父级或任何子级,因此在树中是单独的。
因此,Chrome在那里遵循规范。CCD_ 2元素从不具有非CCD_ 3 CCD_。
问";为什么";问题,因为如果不能引用做出决定的具体会议记录,答案将是一个意见问题。
但是DOM规范清楚地表明Attr
的原始设计是一个错误,例如:
属性节点简称为属性。它们有时被称为content属性,以避免与IDL特性混淆。
属性有一个名称空间(null或非空字符串(、名称空间前缀(null或非空字符串(,本地名称(非空串(、值(字符串(和元素(null或元素(。
注意:
如果今天设计的话,它们只会有一个名字和价值。☹
这似乎只是设计不一定有意义的一种方式。
实际上,我只是想知道如何修复这个设计错误。我在Chrome上发现(现在?(有Attr.prototype.ownerElement属性。为什么这不仅仅是parentElement(或parentNode(,这可能是DOM规范被草率地拼凑在一起的另一个迹象,也许相关人员并不真正知道他们在做什么。
简而言之,功能是存在的,他们只是给它起了一个不同的名字。