Почему здесь есть разница между Chrome и Firefox? - PullRequest
4 голосов
/ 16 марта 2011

Я использую рекурсивную функцию, основанную на 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

Выход Chrome:

clientLeft
scrollHeight
firstElementChild
offsetParent
ч
offsetWidth
isContentEditable
скрыт
previousElementSibling
parentElement
LocalName
дети
ownerDocument
nodeValue
lastElementChild
RowIndex
offsetLeft
тэгу
* 1037 имя класса * Приставка
innerHTML
PreviousSibling
NamespaceURI
ID
childElementCount
InnerText
scrollLeft
clientHeight
выравнивать
TextContent
NextSibling
scrollWidth
offsetHeight
chOff
clientWidth
NODENAME
стиль
языки
scrollTop
offsetTop
ChildNodes
BaseUri
nextElementSibling
VALIGN
sectionRowIndex
ClassList
Название
FirstChild
атрибутов
Набор данных
outerText
клетки
ParentNode
clientTop
TabIndex
contentEditable
outerHTML
реж
LastChild
BGColor
NODETYPE
* 1080 проверка орфографии * Draggable

Все дополнительные свойства, помеченные как true для hasOwnProeperty, вызывают «бесконечное / достаточно для сбоя» повторение в моем коде. Есть ли способ определить, является ли свойство свойства встроенным свойством объекта DOM? Или какое-то другое решение ..

Ответы [ 3 ]

4 голосов
/ 16 марта 2011

Самым простым решением этого является проверка метода .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() { ... };
1 голос
/ 16 марта 2011

Я думаю, @Raynos предлагает хорошее решение в своем ответе.Что касается почему вещи такие разные, я подозреваю, что основная проблема заключается в том, что элемент DOM не является объектом JavaScript, то есть он никоим образом не наследуется от класса JavaScript "Object".Элементы DOM предоставляются средой выполнения и имеют поведение и семантику, которые (обычно) имеют смысл для кода JavaScript, но на самом деле они не являются объектами JavaScript внутри.Таким образом, для меня несколько удивительно, что hasOwnProperty доступен для вызова вообще.

0 голосов
/ 16 марта 2011

Самый простой способ определить, является ли объект объектом DOM, состоит в том, чтобы проверить, имеет ли этот объект свойства nodeName, nodeValue или nodeType.объекты реализуют интерфейс Node и поэтому содержат вышеупомянутые свойства.

...