layui源碼詳細分析系列之流加載模塊
標簽: javascript 源碼 流加載 圖片懶加載 實踐與分析
前言
所謂的流加載實際上是第一種優化手段,通常用于圖片豐富的網站,目的是為了提供更好的用戶體驗。
具體的體現是在頁面初始化時,先加載一小部分內容,當用戶下拉頁面到一定的距離,開始加載另一小部分的內容,直至將所有資源加載呈現,體現的是化整為零的思想,具有較好地用戶體現效果。
自實現流加載以及圖片懶加載功能
流加載功能和圖片懶加載功能是分開實現的,使用原生的JavaScript開發(所有涉及交互效果的案例等都是使用JavaScript來實現,基礎才是王道)現在先說說流加載功能,具體的實現效果圖如下:
上面的是自動帶圖標加載形式的,還有事按鈕形式的加載形式,具體效果圖如下:
下面說說具體的實現思路,實際上就是監聽指定元素的scroll事件,當滾動條滾動時需要做的事情:
- 判斷是否滾動到底部,判斷條件是(假設elem就是外部容器節點), elem.clientHeight+ elem.scrollTop === elem.scrollHeight(容器可是區域的高度 + 滾動條距離頂部的距離 === 容器的滾動高度)
- 當到達條件時就創建加載區域的節點并追加到容器中,當加載成功后,首先刪除加載節點,將元素節點都追加到容器中
- 判斷資源是否完全加載,完全加載就顯示沒有多余的資源
在上面實現思路需要考慮的問題:
- 滾動條向上滾動帶來的重復性問題
我的解決是維持一個狀態數組,記錄任何時刻前一次scroll觸發時的scrollTop,與當前scrollTop比較,只有當前scrollTop大于保存的狀態值,才進行相應的程序處理。
流加載中最主要的是判斷滾動條是否滾動條底部,從而執行程序處理。
圖片懶加載:
所謂的圖片懶加載就是頁面初始化時不加載所有圖片,當用戶滾動到可視區域(就是圖片需要顯示的區域時),加載當前可視區域內的圖片,具體的實現效果如下:
由于上傳圖片有大小限制,可能拉滾動條有點快,不過效果還是可以看到的。
實現的關鍵點:
- 判斷圖片是否在當前可是區域內
實現思路:
- 所有的img標簽的src屬性都是空或沒有src屬性,初始化時顯示當前區域的圖片,判斷的條件(假設圖片節點是image, 容器節點elem):image.offsetTop < elem.clientHeight
- elem容器節點綁定scroll事件,同時也要處理向上滾動帶來的問題
- 設置需要顯示圖片的可視區域,判斷當前圖片是否在可視區域從而是否需要顯示,代碼如下:
// record = [0], data是圖片src的數據源
elem.addEventListener('scroll', function() {
let scrollTop = this.scrollTop,
scrollHeight = this.scrollHeight,
clientHeight = elem.clientHeight;
// 處理向上滾動的重復性問題
if (scrollTop > record[0]) {
record.shift();
record.push(scrollTop);
}
// 只有向下滾動才執行相關程序
if (scrollTop >= record[0]) {
for (let index = 0; index < images.length; index++) {
let image = images[index],
offsetTop = image.offsetTop,
start = scrollTop,
end = start + clientHeight;
// 核心代碼,圖片顯示的可視區域: scrollTop ~ scollTop + clientHeight
if (offsetTop >= start && offsetTop <= end) {
if (!image.src) {
setTimeout(function() {
image.src = data[index];
}, 300);
}
}
}
}
});
代碼主要組織結構圖如下:
下面說說layui中流加載模塊的實現,該內置模塊使用JQuery來實現,對于流加載以及圖片懶加載實現思想,我上面的實現思路跟它的相似,核心代碼還是有所區別,下面主要說說區別點:
- layui內置流加載模塊,考慮到容器元素是全局的情況處理, 作者考慮的很全面
- 內置模塊對外提供api支持用于自實現具體的容器元素
- layui該內置模塊實現在操作的過程中更加流暢自然
該內置模塊代碼組織結構圖如下:
該模塊組織非常簡潔明了,load是用于處理流加載,lazyimg是處理圖片懶加載的。
layui框架內置模塊flow.js的詳細代碼注釋以及我自己實現的demo的源代碼會上傳到我的Github上,與君共進步。
智能推薦
LiveData詳細分析
目錄介紹 01.LiveData是什么東西 02.使用LiveData的優勢 03.使用LiveData的步驟 04.簡單使用LiveData 05.observe()和observerForever() 06.LiveData原理介紹 07.observe訂閱源碼分析 08.setValue發送源碼分析 09.observeForever源碼 10.LiveData源碼總結 00.使用LiveD...
Lifecycle詳細分析
Lifecycle源碼分析 目錄介紹 01.Lifecycle的作用是什么 02.Lifecycle的簡單使用 03.Lifecycle的使用場景 04.如何實現生命周期感知 05.注解方法如何被調用 06.addObserver調用分析 07.知識點梳理和總結一下 00.使用AAC實現bus事件總線 利用LiveData實現事件總線,替代EventBus。充分利用了生命周期感知功能,可以在act...
ConcurrentHashmap 詳細分析
詳盡的分析 JDK8 后的ConcurrentHashmap,思路分析輔以源碼走讀,徹底讀懂 ConcurrentHashmap。 簡介 放入數據 容器元素總數更新 容器擴容 協助擴容 遍歷 簡介 在從 JDK8 開始,為了提高并發度,ConcurrentHashMap的源碼進行了很大的調整。在 JDK7 中,采用的是分段鎖的思路。簡單的說,就是ConcurrentHashMap是由多個HashM...
ION詳細分析
參考: http://blog.csdn.net/armwind/article/details/53454251?locationNum=2&fps=1 代碼路徑 驅動代碼: kernel-3.18/drivers/staging/android/ion Native lib代碼: system\core\libion & vendor/mediatek/proprietary/...
CMA 詳細分析
關于CMA的config @LINUX/android/kernel/arch/arm/configs/msm8909_defconfig CONFIG_CMA=y 已經打開 # CONFIG_CMA_DEBUG is not set # # Default contiguous memory area size: # CONFIG_CMA_SIZE_MBYTES=8 //兩個配對定義 CONFI...
猜你喜歡
MapReduce詳細分析
一、MapReduce概述 1、定義 MapReduce核心功能是將用戶編寫的業務邏輯代碼和自帶默認組件整合成一個完整的分布式運算程序,并發運行在一個Hadoop集群 上。 2、MR進程 一個完整的MapR educe程序在分布式運行時有三類實例進程: **Mr AppMaster:**負責整個程序的過程調度及狀態協調。 MapTask:負責Map階段的整個數據處理流程。 ReduceTask:負...
freemarker + ItextRender 根據模板生成PDF文件
1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...
電腦空間不夠了?教你一個小秒招快速清理 Docker 占用的磁盤空間!
Docker 很占用空間,每當我們運行容器、拉取鏡像、部署應用、構建自己的鏡像時,我們的磁盤空間會被大量占用。 如果你也被這個問題所困擾,咱們就一起看一下 Docker 是如何使用磁盤空間的,以及如何回收。 docker 占用的空間可以通過下面的命令查看: TYPE 列出了docker 使用磁盤的 4 種類型: Images:所有鏡像占用的空間,包括拉取下來的鏡像,和本地構建的。 Con...
requests實現全自動PPT模板
http://www.1ppt.com/moban/ 可以免費的下載PPT模板,當然如果要人工一個個下,還是挺麻煩的,我們可以利用requests輕松下載 訪問這個主頁,我們可以看到下面的樣式 點每一個PPT模板的圖片,我們可以進入到詳細的信息頁面,翻到下面,我們可以看到對應的下載地址 點擊這個下載的按鈕,我們便可以下載對應的PPT壓縮包 那我們就開始做吧 首先,查看網頁的源代碼,我們可以看到每一...