Не уверен, что есть решение этой проблемы. Я хочу знать, есть ли способ обнаружить, когда браузер фактически обновляет интерфейс.Возможно ли обнаружить перерисовку/оплату в браузере?
Допустим, я хочу добавить класс к элементу непосредственно перед тем, как запустить запущенный синхронный блок кода после запуска синхронной функции, класс будет удален.
el.classList.add('waiting');
longRunningSynchronousTask();
el.classList.remove('waiting');
Если я запустил этот код, начнется работа по длительной работе и заблокирует пользовательский интерфейс перед добавлением класса. Я пробовал использовать MutationObserver
и проверял элемент с помощью getComputedStyle
, но это не работает, потому что они не отражают, когда обновление в реальном времени пользовательского интерфейса.
Использование рабочего может быть лучшим решением (отбросьте длинный код в рабочем месте и опубликуйте сообщение, когда оно будет завершено, чтобы удалить класс). На самом деле это не вариант, из-за необходимости поддержки старых браузеров.
Единственное решение, которое работает вне работника, использует setTimeout
. Мне бы хотелось узнать, столкнулся ли кто-нибудь с этой проблемой, и если есть какой-либо способ обнаружить перерисовку/перепланировку пользовательского интерфейса в браузере.
См. Мой пример для лучшей иллюстрации проблемы.
const el = document.querySelector('.target');
const isRed = c => c === 'red' || 'rgb(255, 0, 0)';
let classActuallyApplied = false;
let requestId;
const longRunningTask = (mil, onComplete) => {
if (classActuallyApplied) {
cancelAnimationFrame(requestId);
var start = new Date().getTime();
while (new Date().getTime() < start + mil);
onComplete();
} else {
requestId = requestAnimationFrame(longRunningTask.bind(null, mil, onComplete));
}
}
const observer = new MutationObserver(function(mutations) {
\t classActuallyApplied = mutations
\t .filter(mutation => {
\t \t \t return mutation.type === 'attributes' &&
\t mutation.attributeName === 'class' &&
mutation.target.classList.contains('waiting');
\t \t }).length > 0;
});
const observerConfig = {
\t attributes: true,
\t childList: false,
\t characterData: false
};
observer.observe(el, observerConfig);
el.addEventListener('click', e => {
\t el.classList.add('waiting');
longRunningTask(1000 * 5,() => {
\t // el.classList.remove('waiting');
});
});
.target {
height: 100px;
width: 100px;
background-color: gray;
}
.waiting {
background-color: red;
}
<div class="target">
target
</div>
Вы хотите его обнаружить или вызвать? Я не понимаю, какой смысл обнаружить в вашем случае. –
Если вы знаете условия, которые заставляют пользовательский интерфейс обновляться в вашем коде, тогда просто добавьте соответствующие уточнения там. Если он основан на изменении размера окна, просто добавьте соответствующие слушатели. –
@ DenysSéguret Я хочу обнаружить, когда пользовательский интерфейс обновлен. Если я добавлю класс 'ожидания', например, он изменит цвет текста на красный. Я хочу знать, когда пользовательский интерфейс был обновлен для пользователя. Как только он будет обновлен, я могу начать свою долговременную задачу. –