設置div的overflow屬性,可以使得該div具有滾動效果,下面以div中包含的是table來舉例。
當table的元素較多,以至于超出div的顯示范圍的話,觀察下該div元素的以下3個屬性:
clientHeight是div的顯示高度,scrollHeight是整個table的高度,scrollTop是上方溢出區高度,注意下,下方溢出高度沒有直接的屬性,需要計算得到,就是scrollHeight-clientHeight-scrollTop
有時候,我們在界面上不提供上一頁、下一頁這樣的按鈕,而是通過滾動(PC上通過鼠標滾動來實現,觸摸屏通過手指在屏幕上滑動來實現)來加載前面或后面的數據,當向上滾動時如果上方溢出區高度小于某個閾值時加載前面的記錄,當向下滾動時如果下方溢出區高度小于某個閾值時加載后面的記錄。向后追加數據后,當前可視區域內容不會有變化,而向前插入數據的話,為了不影響可視區域內容,我們可以將scrollTop調整下高度,具體增大值為插入后的scrollHeight與插入前的scrollHeight之差。
從內存和性能方面考慮,html的table中元素應該有一個數量限制,不應該只允許添加而從不刪除,所以可以在添加數據后進行判斷,如果超限則執行刪除,向前插入則刪除最后的行,向后插入則刪除最先的行。
有scroll事件,但是沒有向上滾動或者向下滾動事件,滾動的方向是需要計算判斷的,比如保存上次滾動時的scrollTop,跟當前的scrollTop進行比較,當前的大,則是向下滾動,當前的小,則是向上滾動。
這樣基本完成了設計,但是仍有一些坑,一般數據的獲取是從后端http異步調用得到,會花一些時間,而scroll的事件是瀏覽器前端觸發,在數據獲取期間,不應該繼續向后端發起數據獲取請求,每次數據獲取完成時,再允許向后端發起數據獲取請求,可以設置一個變量來標識是否在進行數據獲取處理。還有一個可能遇到的坑,存在一定概率發生,當上次滾動事件完成時,可視區域正好停在滾動區域頂部或者底部,這時如果向上滾動或者向下滾動時,瀏覽器可能會屏蔽向上滾動事件發生或向下滾動事件發生。那么此時要不要采用其他方式來觸發呢?可以的,此時不能只監聽scoll事件了,對于鼠標滾動事件(wheel)要監聽下,從事件的deltaY屬性跟此前的值進行比較來判斷是向上滾動還是向下滾動,或者對觸屏的touchstart事件與touchmove事件進行監聽,以判斷是向上滑動還是向下滑動。參考代碼如下:
<script>// 監聽 scroll 事件window.addEventListener('scroll', function() {console.log('Scroll event triggered, scrollTop:', document.documentElement.scrollTop);});// 監聽 wheel 事件(鼠標滾輪或觸摸板)window.addEventListener('wheel', function(event) {console.log('Wheel event triggered, deltaY:', event.deltaY);});// 監聽 touchstart 和 touchmove 事件(觸摸設備)let startY = 0;window.addEventListener('touchstart', function(event) {startY = event.touches[0].clientY; // 記錄觸摸起始位置});window.addEventListener('touchmove', function(event) {const currentY = event.touches[0].clientY; // 獲取當前觸摸位置const deltaY = currentY - startY; // 計算滑動距離console.log('Touchmove event triggered, deltaY:', deltaY);});</script>