我正在使用基于for(... in ..)和hasOwnProperty的递归函数来克隆对象,这在IE和FF中运行良好......但不是Chrome。
使用for(... in ...)迭代对象的成员时,如果对象是DOM对象,则Firefox和Chrome会为hasOwnProperty提供不同的结果。
在Chrome控制台与Firebug(FF)中的控制台中键入以下内容会产生不同的结果:
var t = document.createElement("table");
var tr = t.insertRow(-1);
for(var p in tr) if(tr.hasOwnProperty(p)) console.log(p);
Firefox输出:
构造
addEventListener
Chrome输出
clientLeft
scrollHeight属性
firstElementChild
offsetParent
CH
offsetWidth
isContentEditable
隐藏
previousElementSibling
parentElement
的localName
孩子
ownerDocument
的nodeValue
lastElementChild
rowIndex位置
offsetLeft
标签名
类名
前缀
innerHTML的
previousSibling
的namespaceURI
ID
childElementCount
的innerText
scrollLeft
clientHeight
对齐
的textContent
nextSibling
scrollWidth
的offsetHeight
chOff
clientWidth
节点名称
风格
郎
scrollTop的
的offsetTop
的childNodes
基本URI
nextElementSibling
VALIGN
sectionRowIndex
班级名册
标题
则firstChild
属性
数据集
outerText
细胞
parentNode
clientTop
的tabIndex
CONTENTEDITABLE
outerHTML
DIR
lastChild
BGCOLOR
节点类型
拼写检查
可拖动的
hasOwnProeperty标记为true的所有额外属性导致我的代码中出现“无限/足够崩溃”的错误。有没有办法确定proeperty是否是内置的DOM对象属性?或者其他一些解决方案..
答案 0 :(得分:4)
最简单的解决方案是检查.cloneNode
方法并使用该方法(如果存在)。
这意味着您的克隆方法将检查任何DOM节点并在其上使用预定义的DOM方法。这应该完全避免你的问题。
至于你的实际问题。 Chrome和Firefox似乎不同意原型上的内容以及HTMLTableRowElement对象的内容(以及任何其他元素)。
比较firefox和chrome中的console.dir(HTMLTableRowElement)
。
在firefox中,所有这些属性都存在于HTMLTableRowElement
原型中。在哪里,铬原型只有几个方法。 (delecteCell
和insertCell
)。
在DOM规范中没有说明HTMLElements的属性是应该在原型上还是在对象上明确定义,所以这只是你不应该依赖的东西。
无论哪种方式都使用.cloneNode
,因为它是一种原生方法,因此比用JavaScript编写的任何内容更好/更快。
Chrome伪版实施:
function HTMLTableRowElement() {
...
this.nextSibling = ...;
this.nodeName = ...;
this.nodeType = ...;
...
}
HTMLTableRowElement.prototype.deleteCell = function() { ... };
HTMLTableRowElement.prototype.insertCell = function() { ... };
Firefox伪实现
function HTMLTableRowElement() {
...
}
HTMLTableRowElement.prototype.nextSibling = ...;
HTMLTableRowElement.prototype.nodeName = ...;
HTMLTableRowElement.prototype.nodeType = ...;
...
HTMLTableRowElement.prototype.deleteCell = function() { ... };
HTMLTableRowElement.prototype.insertCell = function() { ... };
答案 1 :(得分:1)
我认为@Raynos在他的回答中提供了一个很好的解决方案。至于为什么事情是如此不同,我怀疑基本问题是DOM元素不是JavaScript对象 - 也就是说,它不以任何方式从JavaScript“Object”类继承。 DOM元素由运行时提供,并且具有(通常)对JavaScript代码有意义的行为和语义,但它们内部并不是真正的JavaScript对象。因此,对我而言,“hasOwnProperty”可以被调用,这有点令人惊讶。
答案 2 :(得分:0)
确定对象是否为DOM对象的最简单方法是检查该对象是否具有nodeName
,nodeValue
或nodeType
属性。
if ( tr.nodeType > 0 ) {
// tr is a DOM object
} else {
// tr is not a DOM object
}
所有DOM对象都实现Node interface,因此包含上述属性。