Почему здесь есть разница между Chrome и Firefox?
Я использую рекурсивную функцию, основанную на for(.. in ..) и hasOwnProperty для клонирования объектов, которая отлично работает в IE и FF... но не в Chrome.
При переборе элементов объекта с помощью for(... in ...) Firefox и Chrome дают разные результаты для hasOwnProperty, если объект является объектом DOM.
Ввод следующего в консоли 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
Хромированный выход:
clientLeft
scrollHeight
firstElementChild
offsetParent
ч
offsetWidth
isContentEditable
скрытый
previousElementSibling
parentElement
LocalName
дети
ownerDocument
nodeValue
lastElementChild
RowIndex
offsetLeft
название тэга
имя класса
префикс
innerHTML
PreviousSibling
NamespaceURI
Я бы
childElementCount
InnerText
scrollLeft
clientHeight
выравнивать
TextContent
NextSibling
scrollWidth
offsetHeight
chOff
clientWidth
NODENAME
стиль
языки
scrollTop
offsetTop
ChildNodes
BaseUri
nextElementSibling
VALIGN
sectionRowIndex
ClassList
заглавие
Первый ребенок
атрибуты
Набор данных
outerText
ячейки
ParentNode
clientTop
TabIndex
contentEditable
outerHTML
реж
последний ребенок
BGColor
NODETYPE
проверка орфографии
перетаскиваемый
Все дополнительные свойства, помеченные как true для hasOwnProeperty, вызывают в моем коде "бесконечное / достаточное количество аварий". Есть ли способ определить, является ли свойство свойства встроенным свойством объекта DOM? Или какое-то другое решение..
3 ответа
Самым простым решением для этого является проверка .cloneNode
метод и использование этого, если оно существует.
Это означает, что ваш метод клонирования будет проверять наличие любых узлов DOM и использовать на нем предварительно определенный метод DOM. Это должно полностью избежать вашей проблемы.
Что касается вашей актуальной проблемы. Похоже, что Chrome и Firefox не согласны с тем, что принадлежит прототипу и что принадлежит объекту для HTMLTableRowElement (и любого другого элемента, а также).
сравнить console.dir(HTMLTableRowElement)
как в Firefox, так и в Chrome.
В Firefox все эти свойства живут на HTMLTableRowElement
прототип. Где в качестве прототипа Chrome есть только несколько методов. (delecteCell
а также insertCell
).
В спецификации DOM нигде не сказано, должны ли свойства прототипа HTMLElements определяться в прототипе или в конкретном объекте, так что на это просто не стоит полагаться.
В любом случае использовать .cloneNode
потому что это нативный метод и, следовательно, лучше / быстрее, чем все, что вы можете написать в JavaScript.
Реализация Chrome Psuedo:
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() { ... };
Я думаю, что @Raynos предлагает хорошее решение в своем ответе. Относительно того, почему все так по-разному, я подозреваю, что основная проблема заключается в том, что элемент DOM не является объектом JavaScript, то есть он никоим образом не наследуется от класса JavaScript "Объект". Элементы DOM предоставляются средой выполнения и имеют поведение и семантику, которые (обычно) имеют смысл для кода JavaScript, но на самом деле они не являются объектами JavaScript внутри. Таким образом, для меня несколько удивительно, что hasOwnProperty доступен для вызова вообще.
Самый простой способ определить, является ли объект объектом DOM, состоит в том, чтобы проверить, имеет ли этот объект nodeName
, nodeValue
или же nodeType
свойства.
if ( tr.nodeType > 0 ) {
// tr is a DOM object
} else {
// tr is not a DOM object
}
Все объекты DOM реализуют интерфейс Node и поэтому содержат вышеупомянутые свойства.