Почему чтение измерений DOM запускает макет / перекомпоновку? - PullRequest
2 голосов
/ 23 февраля 2020

Я часто читаю, что изменение стиля после прочтения стиля элемента является плохой практикой, поскольку вызывает ненужное перекомпонование. Рассмотрим этот код из здесь :

Неверный код:

elementA.className = "a-style";
var heightA = elementA.offsetHeight;  // layout is needed
elementB.className = "b-style";       // invalidates the layout
var heightB = elementB.offsetHeight;  // layout is needed again

Хороший код:

elementA.className = "a-style";
elementB.className = "b-style";
var heightA = elementA.offsetHeight;   // layout is needed and calculated
var heightB = elementB.offsetHeight;   // layout is up-to-date (no work)

Мне любопытно узнать, почему elementA.offsetHeight вызовет макет? Здесь мы просто читаем уже примененные изменения, а не применяем изменения (как в случае elementA.className = "a-style").

1 Ответ

3 голосов
/ 23 февраля 2020

Здесь мы просто читаем уже внесенные изменения ...

Не совсем. Присвоение className означает, что браузер должен перекомпоноваться, но это не значит, что уже перекомпоновал , когда вы закончите присваивание. Он может подождать (в современных браузерах, подождет) до следующего рисования, что не произойдет, пока не завершится (по крайней мере) текущий код JavaScript.

Но когда вы читаете вычисляемое свойство, такое как clientHeight, браузер должен приостановить код JavaScript и переформатировать страницу, чтобы он мог вернуть точное число. Итак, ваш «хороший» код делает это:

elementA.className = "a-style";        // marks the layout stale
elementB.className = "b-style";        // marks the layout stale (no change)
var heightA = elementA.offsetHeight;   // triggers reflow
var heightB = elementB.offsetHeight;   // no need for reflow, the layout isn't stale
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...