前言
近來有需求要做分頁,聽起來可能有點Low。 所以我要把Low的事情做得有點逼格。
分頁本身沒啥,但是資料量起來了,比如十萬。 要是不做點處理, 那你的頁面估計爽得很,機器也爽得很。 放心,我不會讓你這麼爽。
大量資料展現方案
比較流行的當然是虛擬滾動(無限滾動)。
- 始終展示的是有限的固定節點。
- 外層建立滾動層。
一句話,就是反覆利用固定節點展現資料。
其中還有兩個點
何時需要載入新的分頁資料
- scrollTop , clientHeight, scrollHeight
- IntersectionObserver (chrome 55+)
如何知道容器寬高變化
本文就圍繞著這個展開
因為使用的是react框架,使用了 react-window, react-window就是用來展現海量資料的react列表元件。
因為專案需要,還要不通尺寸一行展現不同數量的資料。 肯定有人就說,監聽window.resize。
沒錯,監聽resize一定程度,但是window.resize, 並不能讓我知道容器本身的尺寸,當
然可以通過getComputedStyle獲取。 要是window沒有resize的情況呢。
我就想實時的知道尺寸的變化。
尺寸變化監測方案
監測元素resize這裡有幾種方案的測試和原始碼。
Cross-Browser, Event-based, Element Resize Detection
思路:
如果IE,直接註冊onresize(這個點贊啊)
否則: 建立 type為text/html的object
設定position為absolute, 高度100%, 寬度100% (這樣可以獲得父容器的寬高)
設定pointer-events:none,利用點選穿透(讓object窗體變成幽靈)
object元素的高度變化後,通知訂閱者
resize事件節流
問題:
- 建立object
- 事件處理函式掛載了元素本身上
javascript-detect-element-resize
建立三個子元素,利用scroll事件來監測變化。
原理:
https://zhuanlan.zhihu.com/p/24887312
The scroll event is fired when the document view or an element has been scrolled.
當文件檢視或者元素滾動的時候會觸發 scroll 事件。
也就是說元素滾動的時候會觸發這個事件,那麼什麼時候元素會滾動?當元素大於其父級元素,且父級元素允許其滾動的時候,該元素可以進行滾動。
換句話說,元素可以滾動意味著父子元素大小不一致,這是這個方法的核心。
那麼我們需要讓元素大小發生改變時,使得 scrollLeft 或者 scrollTop 發生改變,從而觸發 scroll 事件,進一步得知其大小發生了改變。
visibility: hidden; opacity: 0; position: absolute;讓自己變得虛無
addEventListener("scroll", scrollListener, true) 在捕捉階段攔截事件,使用false無效
div.expand-trigger 變大
div.expand-trigger 變小
animationstart來監聽顯示,比如style.display = 'none'然後style.display = 'block'
問題:
- 額外建立四個元素節點以及一個style節點
- 事件都掛載了元素本身身上,
ResizeObserver
原生自帶的方案, 相容性並不高, resize-observer-polyfill 基於resize和MutationOberver的polyfill實現了ResizeObserver。
const resizeObserver = new ResizeObserver(entries => {
for (let entry of entries) {
console.log(entry.target.id, `height:${entry.contentRect.height} width:${entry.contentRect.width}`);
}
});
resizeObserver.observe(document.querySelector('#my_element'));
resizeObserver.observe(document.querySelector('#my_element2'));
此外
當然,我覺得還
- 定時器 + getComputedStyle 也是很低成本的實現。
- resize + MutationOberver 也是很簡單的方案。