2016-04-21 98 views
1

不確定是否有解決此問題的方法。我想知道是否有辦法檢測瀏覽器實際上更新UI的時間。是否可以在瀏覽器中檢測重繪/重排?

可以說我想在運行一個長時間運行的同步代碼塊之前向一個元素添加一個類,在同步函數運行之後,該類將被刪除。

el.classList.add('waiting'); 
longRunningSynchronousTask(); 
el.classList.remove('waiting'); 

如果我運行此代碼,長時間運行的任務將開始,並在添加類之前阻止UI。我嘗試使用MutationObserver's,並用getComputedStyle檢查元素,但這不起作用,因爲這些不會反映實時更新UI的時間。

使用工作者可能是最好的解決方案(將工作中的長時間運行的代碼刪除,並在完成刪除類時發佈消息)。由於需要支持舊版瀏覽器,所以這不是我的選擇。

在實施工作者之外工作的唯一解決方案是使用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) { 
 
\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>

+0

你想檢測它或觸發它?我沒有得到什麼檢測點會在你的情況下 –

+0

如果你知道導致你的代碼更新UI的條件,那麼只需在那裏添加適當的標註。如果它基於窗口大小調整,那麼只需添加適當的偵聽器。 –

+0

@DenysSéguret我想要檢測UI何時更新。例如,如果我添加「waiting」類,它會將文本顏色更改爲紅色。我想知道用戶界面何時更新。一旦更新,我可以開始我長時間運行的任務。 –

回答

0

我相信requestIdleCallback是你所期待的。

以同樣的方式,採用requestAnimationFrame使我們能夠正確地調度動畫和最大限度地提高我們打擊60fps的機會,當出現在幀的結束,或者當用戶處於非活動狀態的空閒時間requestIdleCallback將安排工作。

不幸的是,這是一個實驗性功能,僅在Chrome Canary中受支持。

相關問題