Порядок рендеринга в Firefox

Я создаю компонент диаграммы на JavaScript. Он имеет два слоя, визуализируемых отдельно: передний план и задний план.

Чтобы определить необходимый размер фона:

  1. визуализировать передний план
  2. измерить высоту результата
  3. визуализировать передний план и фон вместе

В коде это выглядит так:

var foreground = renderForegroundIntoString();
parentDiv.innerHTML = foreground;
var height = parentDiv.children[0].clientHeight;
var background = renderBackgroundIntoString(height);
parentDiv.innerHTML = foreground + background;

Используя IE7, это совсем несложно. Однако Firefox2 не хочет сразу отображать parentDiv.innerHTML, поэтому я не могу прочитать высоту переднего плана.

Когда Firefox выполняет рендеринг и как я могу отложить генерацию фона до завершения рендеринга переднего плана, или есть какой-либо альтернативный способ определить высоту моих элементов переднего плана?

[Добавлен после проверки ответа Дэна (спасибо Дэн)]

В теле метода обратного вызова (вызванного setTimeout(...)), я вижу, рендеринг innerHTML еще не завершен.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
0
571
2

Ответы 2

Вы никогда не должны полагаться на то, что что-то, что вы только что вставили в DOM, отображается следующей строкой кода. Все браузеры в некоторой степени группируют эти изменения вместе, и может быть сложно определить, когда и почему.

Лучший способ справиться с этим - выполнить вторую часть в ответ на какое-то событие. Хотя не похоже, что есть хороший вариант, который вы можете использовать в этой ситуации, поэтому, если это не удается, вы можете запустить вторую часть с помощью:

setTimeout(renderBackground, 0)

Это обеспечит завершение текущего потока до выполнения второй части кода.

Я не думаю, что вам нужен parentDiv.children [0] (в любом случае дочерние элементы не являются допустимым свойством в FF3), вместо этого вы хотите parentDiv.childNodes [0], но обратите внимание, что это включает текстовые узлы, которые могут не иметь высоты. Вы можете попробовать зацикливаться, ожидая, пока потомки parentDiv будут отображаться следующим образом:

function getRenderedHeight(parentDiv) {
if (parentDiv.childNodes) {
  var i = 0;
  while (parentDiv.childNodes[i].nodeType == 3) { i++; }
  //Now parentDiv.childNodes[i] is your first non-text child
  return parentDiv.childNodes[i].clientHeight;
  //your other code here ...
} else {
  setTimeout("isRendered("+parentDiv+")",200);
}
}

а затем вызвать: getRenderedHeight (parentDiv) после установки innerHTML.

В любом случае, надеюсь, что это дает некоторые идеи.

Другие вопросы по теме