簡體   English   中英

在繁重的渲染/計算過程中凍結后,如何防止滾動位置跳動?

[英]How can I prevent scroll position jump after a freeze during a heavy render/calculations?

在重度渲染過程中滾動一些列表時(例如50個Highchart項目),我的滾動凍結了(很好)。 問題是在加載所有圖表之后,滾動(被凍結)的“跳轉”到列表的末尾(向上或向下,取決於滾動方向)。 完成所有較重的渲染后,是否有辦法從滾動位置繼續滾動(例如30%)?

我嘗試為列表元素添加樣式,以消除重渲染開始之前的滾動,例如“溢出:隱藏”,然后在所有渲染結束后將“溢出:滾動”添加回該元素。 但這無濟於事,仍然會經歷“跳躍”。

我嘗試過的看起來像這樣:

// inner-container is a class name of all scrollable elements on the page that I need to control
// content-wrapper is a list inside of the container, position for that I want to be consistent after a render (without "jumps")

const elements = document.getElementsByClassName("inner-container");
window.elCoords = [];
for (let el of elements) {
   el.style.overflowY = 'hidden';
   el.style.pointerEvents = 'none';
   const coords = el.getElementsByClassName('content-wrapper')[0].getBoundingClientRect();
   window.elCoords.push(coords.y)
}

渲染結束后,我刪除了“ overflow:hidden”樣式,以便元素可以再次滾動並設置滾動位置,就像開始繁重的渲染之前一樣:

const elements = document.getElementsByClassName("inner-container");
let index = 0;
for (let el of elements) {
   const inner = el.getElementsByClassName('content-wrapper')[0];
   inner.scrollTo({
      top: window.elCoords[index],
      behavior: 'smooth'
   });
   index += 1;

   el.style.overflowY = 'scroll';
   el.style.pointerEvents = 'all';
}

實際:沉重的渲染結束后,滾動位置跳到可滾動容器的末尾

預期:重渲染結束后,滾動應從重渲染開始之前的位置繼續

瀏覽器是單線程的。 在運行計算時,實際上不會阻止UI事件,但會將它們排隊(滾動事件,鼠標事件,鍵盤事件等)。 當執行可以繼續時,將刷新隊列,因此將向前滾動發生的所有滾動以及其他事件。

在開始計算之前,您可以防止在頁面上滾動,並在計算完成后再次允許它滾動:

function preventDefault(event) {
  event.preventDefault();
}

document.addEventListener('scroll', preventDefault);
// and other events ('wheel', DOMMouseScroll', etc.)
// Heavy rendering...
// ...
document.removeEventListener('scroll', preventDefault);

要么:

window.onscroll = function () { window.scrollTo(0, 0); };
// Heavy rendering...
window.onscroll = null;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM