element.innerHTML = элемент.innerHTML изменяет макет в Firefox 4

#html #firefox #rendering #firefox4

#HTML #firefox #рендеринг #firefox4

Вопрос:

Я обнаружил странную проблему при просмотре старой документации Ext,http://extjs.cachefly.net/ext-3.2.1/docs/?class=Ext.grid .PropertyGrid

Макет окна наследования (вверху справа) несколько нарушен.

сломанный макет http://img339.imageshack.us/img339/374/bildschirmfoto20110427u.png

Но после выполнения

 var resblock = document.getElementById('docs-Ext.grid.PropertyGrid').getElementsByClassName('res-block-inner')[0];
resblock.innerHTML = resblock.innerHTML; // should be a no-op(?)
  

все в порядке.

макет в порядке http://img204.imageshack.us/img204/374/bildschirmfoto20110427u.png

Как это может быть? Ошибка в Firefox 4?


Отредактируйте минимальный тестовый пример: http://jsfiddle.net/uZ3eC /

Комментарии:

1. Есть много случаев, в которых настройка x.innerHTML = x.innerHTML не является нерабочей. В частности, в любой момент DOM является чем-то, что не может быть создано синтаксическим анализатором. В качестве простого примера, если вы создадите DOM, в котором у div есть img дочерний элемент и у которого img есть дочерний элемент textnode, а затем установите для innerHTML из div самого себя, результат не будет соответствовать тому, что у вас было до установки innerHTML.

2. @Boris: Я проверил ваш пример, но я думаю, что это ошибка, поскольку в спецификациях сказано «Если текущий узел является элементом […] img […], то переходите к следующему дочернему узлу [div, то есть] на этом этапе.», поэтому img дочерние узлы должны быть пропущены при сериализации.

3. Ты говоришь то же самое, что и Борис. Дочерние элементы img элемента теряются во время сериализации, поэтому сериализация и повторный анализ не вернут вас к тому, с чего вы начали. т. Е. Это не сбой.

Ответ №1:

Да, это похоже на ошибку в том, как Firefox 4 обрабатывает окончания строк.

Элемент resblock — это <pre> элемент, содержащий несколько текстовых узлов, которые имеют дело с новыми строками и отступами. Когда они создаются с помощью скриптов, они содержат ВОЗВРАТ КАРЕТКИ (U 000D), за которым следует последовательность неразрывных пробелов.

Однако после запуска resblock.innerHTML = resblock.innerHTML; они теперь содержат ПЕРЕВОД СТРОКИ (U 000A), за которым следуют неразрывные пробелы.

Похоже, что Firefox 4 обрабатывает символ перевода строки только как разрыв строки и отображает части иерархии классов в новых строках.

Редактировать: Что сказал Борис.

В разделе спецификации проекта HTML5 8.2.2.3 Предварительная обработка входного потока говорится:

Символы ВОЗВРАТА КАРЕТКИ U 000D (CR) и символы перевода строки U 000A (LF) обрабатываются особым образом. Все символы CR, за которыми следуют символы LF, должны быть удалены, а любые символы CR, за которыми не следуют символы LF, должны быть преобразованы в символы LF. Таким образом, новые строки в доменах HTML представлены символами LF, и во входных данных на этапе токенизации никогда не используются символы CR.

Комментарии:

1. На самом деле, похоже, что поведение Firefox 4 правильное. HTML5 требует, чтобы во время синтаксического анализа отдельный CR был преобразован в LF. Итак, если вы вводите CR в DOM вручную (что невозможно сделать с помощью синтаксического анализатора; только с помощью скриптов), то вы создаете DOM, который не будет проходить цикл при сериализации и повторной обработке.

2. Хороший момент, но я хочу отметить, что HTML в моем примере не был создан скриптом ( исходный код с той же проблемой ), поэтому анализатор должен преобразовать перевод строк при первом запуске (?)

3. @Pumbaa80 — «Предварительная обработка входного потока» происходит перед преобразованием ссылок на символы. Таким образом, хотя во входных данных для токенизатора нет CRS, amp;#13; все равно станет символом CR на этапе построения дерева и, следовательно, в DOM. Сериализация и повторный анализ, согласно innerHTML, затем преобразуют их в символы LF в соответствии с правилом «Предварительной обработки входного потока».

4. Ах, да, я забыл, что вы также можете вводить CR с использованием символьных объектов, а не только скриптов….

5. Ага, я наконец-то понял 😉 Похоже, алгоритм обработки входного потока в этом случае несколько неудобен.