不确定是否有解决此问题的方法。我想知道是否有一种方法可以检测浏览器实际更新UI的时间。
假设我想在运行长时间同步代码块之前向元素添加一个类,在同步函数运行后,该类将被删除。
el.classList.add('waiting');
longRunningSynchronousTask();
el.classList.remove('waiting');
如果我运行这段代码,长时间的任务将会启动,并在添加类之前阻止UI。我尝试使用
MutationObserver
和getComputedStyle
检查元素,但这并不起作用,因为它们不能反映出实时更新UI的情况。使用worker可能是最好的解决方案(将长时间运行的代码放入worker中,并在其完成后发布消息以删除类)。对于我来说,这不是一个真正的选项,因为需要支持旧版浏览器。
除了实现worker外,唯一可行的解决方案是使用
setTimeout
。我想知道是否有人遇到过这个问题,是否有任何方法可以检测浏览器中UI的重绘/回流。请查看我的示例,以更好地说明问题。
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) {
classActuallyApplied = mutations
.filter(mutation => {
return mutation.type === 'attributes' &&
mutation.attributeName === 'class' &&
mutation.target.classList.contains('waiting');
}).length > 0;
});
const observerConfig = {
attributes: true,
childList: false,
characterData: false
};
observer.observe(el, observerConfig);
el.addEventListener('click', e => {
el.classList.add('waiting');
longRunningTask(1000 * 5, () => {
// el.classList.remove('waiting');
});
});
.target {
height: 100px;
width: 100px;
background-color: gray;
}
.waiting {
background-color: red;
}
<div class="target">
target
</div>
waiting
类,例如,将会把文字颜色改成红色。我想知道用户界面何时已经被更新。一旦它被更新,我就可以开始我的长时间运行任务。 - Nicholas Mitchell