摘要:幾個(gè)月前實(shí)現(xiàn)的一個(gè)圖片懶加載庫(kù),地址。而這是我們可以優(yōu)化的地方,這里我們使用函數(shù)去抖,調(diào)整后的代碼如下至此,也算是實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的圖片懶加載庫(kù)了,如有不足之處歡迎指正,大家一起交流交流
幾個(gè)月前實(shí)現(xiàn)的一個(gè)圖片懶加載庫(kù)lazyload.js,github 地址。
需要實(shí)現(xiàn)的效果相信大家都在網(wǎng)頁(yè)中體驗(yàn)過(guò)圖片懶加載,它應(yīng)該有這樣的效果:當(dāng)圖片進(jìn)入我們的可視區(qū)時(shí),加載這些圖片。其原因相信大家都懂的——提高用戶體驗(yàn)。
那么在代碼中,我們就應(yīng)該實(shí)現(xiàn)一下幾點(diǎn)功能:
1.當(dāng)頁(yè)面加載完成時(shí),先對(duì)可視區(qū)的圖片進(jìn)行加載;
2.給 scroll 及 resize 事件添加監(jiān)聽(tīng);
3.當(dāng)上述事件觸發(fā)時(shí),對(duì)在可視區(qū)的圖片進(jìn)行加載,并將加載過(guò)的圖片移除。
經(jīng)過(guò)上面的分析,我們一步一步來(lái)實(shí)現(xiàn)圖片懶加載。首先,我們先制定一些規(guī)則:
1.需要懶加載的圖片標(biāo)簽應(yīng)該帶有值為 lazyload-img 的類;
2.需要懶加載的圖片標(biāo)簽應(yīng)該帶有屬性 data-src ,其值為圖片的鏈接。
function LazyLoad() { // 將所有需要懶加載的圖片緩存在 imgList 數(shù)組中 this.imgList = [].slice.call(document.querySelectorAll(".lazyload-img")); // 進(jìn)行初始化操作 this.init(); }
接下來(lái)想想我們的 init 方法應(yīng)該做些什么?圖片的加載是通過(guò)事件觸發(fā)實(shí)現(xiàn)的,所以我在初始化的方法主要做的事情就是添加事件監(jiān)聽(tīng)。
把 init 方法的實(shí)現(xiàn)放到最后來(lái)講,接下來(lái)先來(lái)實(shí)現(xiàn)判斷圖片是否在可視區(qū)的方法 isInViewport。
isInViewport方法的實(shí)現(xiàn)在上代碼前先來(lái)講講 getBoundingClientRect 這貨,不知道大家對(duì)她了解多少。MDN上給出的定義是這樣的:
Element.getBoundingClientRect()方法返回元素的大小及其相對(duì)于視口的位置。
什么意思呢,就是調(diào)用了這個(gè)方法后,返回了一個(gè)包含元素的寬高及其相對(duì)于瀏覽器視口左上角的位置信息。嗯.. 沒(méi)看懂:( 簡(jiǎn)單點(diǎn)說(shuō)呢,這個(gè)方法返回了一個(gè)對(duì)象,長(zhǎng)這樣:
{ bottom: xx, left: xx, right: xx, top: xx, height: xx, width: xx }
如果還是不太明白,可以直接到MDN看看。建議大家直接在控制臺(tái)試試,說(shuō)得再多不如動(dòng)手試一試。
那了解這個(gè)方法后,有啥用?當(dāng)然是用來(lái)判斷圖片是否在可視區(qū)咯,那我們來(lái)看看判斷的邏輯:
LazyLoad.prototype.isInViewport = function (img) { var clientH = document.documentElement.clientHeight, // 瀏覽器視口高度 clientW = document.documentElement.clientWidth, // 瀏覽器視口寬度 imgPosOb = img.getBoundingClientRect(), // 獲取img的位置信息 imgT = imgPosOb.top, imgL = imgPosOb.left, imgH = imgPosOb.height, imgW = imgPosOb.width; // 判斷邏輯 // 不清楚的同學(xué)可以在草稿紙上畫個(gè)圖 if( (imgT > -imgH && imgT < clientH) && (imgL > -imgW && imgL < clientW) ) { // inViewport return true; } else { return false; } }
我們還有什么功能沒(méi)實(shí)現(xiàn)?當(dāng)然還有最重要的加載!
實(shí)現(xiàn)圖片加載這一步?jīng)]啥好說(shuō)的,直接上代碼:
// 參數(shù) imgList 是要加載的圖片列表 LazyLoad.prototype.loadImg = function (inVpImgList) { var len = inVpImgList.length; var src = ""; for (var i = 0; i < len; i++) { src = inVpImgList[i].getAttribute("data-src"); inVpImgList[i].src = src; inVpImgList[i].removeAttribute("data-src"); this.removeItem(inVpImgList[i]); } }; // 不要忘了這一步 // 把加載過(guò)的圖片移除 LazyLoad.prototype.removeItem = function (img) { var idx = this.imgList.indexOf(img); if(idx > -1) { this.imgList.splice(idx, 1); } };init方法的實(shí)現(xiàn)
最后,來(lái)完成我們的初始化方法:
LazyLoad.prototype.init = function () { var self = this; // callback函數(shù)即我們定義的事件觸發(fā)后的回調(diào)函數(shù) function callback() { var imgInVp = []; var len = self.imgList.length; for (var i = 0; i < len; i++) { if(self.isInViewport(self.imgList[i])) { imgInVp.push(self.imgList[i]); } } self.loadImg(imgInVp); } callback(); document.addEventListener("scroll", callback, false); window.addEventListener("resize", callback, false); };
可能有哪位細(xì)心的小伙伴會(huì)發(fā)現(xiàn)我在 init 方法中調(diào)用了一次 callback。讓我們?cè)倩仡^看看功能分析的第一點(diǎn),你就明白了。那到這咱就完事了?不,還得優(yōu)化一下。
優(yōu)化我們知道當(dāng)我們?cè)诙虝r(shí)間內(nèi),連續(xù)地改變?yōu)g覽器窗口大小或者滾動(dòng)頁(yè)面,會(huì)連續(xù)多次地觸發(fā) resize 和 scroll 事件。而這是我們可以優(yōu)化的地方,這里我們使用函數(shù)去抖,調(diào)整后的代碼如下:
LazyLoad.prototype.init = function () { var self = this, timer = null; function callback() { timer && clearTimeout(timer); timer = setTimeout(function () { var imgInVp = []; var len = self.imgList.length; for (var i = 0; i < len; i++) { if(self.isInViewport(self.imgList[i])) { imgInVp.push(self.imgList[i]); } } self.loadImg(imgInVp); }, 100); } callback(); document.addEventListener("scroll", callback, false); window.addEventListener("resize", callback, false); };
至此,也算是實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的圖片懶加載庫(kù)了,如有不足之處歡迎指正,大家一起交流交流 :)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/84879.html
摘要:前言淘寶新勢(shì)力周春上新是命運(yùn)石鏈路鏈路第一次承接級(jí)大促,面對(duì)級(jí)大促內(nèi)容豐富且復(fù)雜的頁(yè)面需求,鏈路遇到了一些性能問(wèn)題,在未進(jìn)行性能優(yōu)化之前,搭建出來(lái)的頁(yè)面,業(yè)務(wù)方普遍反饋?lái)?yè)面卡頓嚴(yán)重,無(wú)法滑動(dòng)。 前言 淘寶新勢(shì)力周(春上新)是命運(yùn)石kimi鏈路(H5鏈路)第一次承接S級(jí)大促,面對(duì)S級(jí)大促內(nèi)容豐富且復(fù)雜的頁(yè)面需求,kimi鏈路遇到了一些性能問(wèn)題,在未進(jìn)行性能優(yōu)化之前,搭建出來(lái)的頁(yè)面,業(yè)務(wù)方...
摘要:相交比例相交區(qū)域占參照區(qū)域的比例。閾值相交比例如果達(dá)到閾值,則會(huì)觸發(fā)監(jiān)聽(tīng)器的回調(diào)函數(shù)。 意義 懶加載或者可以說(shuō)是延遲加載,針對(duì)非首屏或者用戶看不到的地方延遲加載,有利于頁(yè)面首屏加載速度快、節(jié)約了流量,用戶體驗(yàn)好 實(shí)現(xiàn)方式 傳統(tǒng)H5的懶加載方式都是通過(guò)監(jiān)聽(tīng)頁(yè)面的scroll事件來(lái)實(shí)現(xiàn)的,結(jié)合viewport的高度來(lái)判斷。小程序也類似,通過(guò)監(jiān)聽(tīng)頁(yè)面onPageScroll事件獲取當(dāng)前滾動(dòng)的...
摘要:要注意老舊的瀏覽器不支持的特性,它會(huì)繼續(xù)正常加載屬性引用的圖像。五安全地使用圖片的優(yōu)勢(shì)這里不再贅述,簡(jiǎn)單來(lái)說(shuō) 這篇文章,我們將一起探討,web應(yīng)用中能對(duì)圖片進(jìn)行什么樣的優(yōu)化,以及反思一些負(fù)優(yōu)化手段 一、為什么要對(duì)圖片進(jìn)行優(yōu)化 對(duì)于大多數(shù)前端工程師來(lái)說(shuō),圖片就是UI設(shè)計(jì)師(或者自己)切好的圖,你要做的只是把圖片丟進(jìn)項(xiàng)目中,然后用以鏈接的方式呈現(xiàn)在頁(yè)面上,而且我們也經(jīng)常把精力放在項(xiàng)目的打包...
摘要:景科同學(xué)的想法很簡(jiǎn)單,因?yàn)楸救四壳斑€是一個(gè)前端小白,只有通過(guò)不斷的寫,不斷的學(xué),在與的相愛(ài)相殺中才能更快速的進(jìn)步。本項(xiàng)目是景科同學(xué)自寫自測(cè),雖然比較簡(jiǎn)單,但是不保證沒(méi)有隱藏的。所以如果看官同學(xué)發(fā)現(xiàn)還望留言指正,景科同學(xué)在此以示感謝。 showImg(https://segmentfault.com/img/remote/1460000014251310?w=841&h=630); 本文...
摘要:清楚自己想要什么樣的組件,就自己動(dòng)手?jǐn)]唄。咱們先來(lái)看看它的效果吧如果大家有時(shí)間,窩還是鼓勵(lì)大家自己動(dòng)手實(shí)現(xiàn)一些小插件。于是自己就琢磨能否繼承使用方法同時(shí)保持特有組件特性。需要確保已安裝。 副標(biāo)題----為什么我要寫這個(gè) react 插件 圖片懶加載是項(xiàng)目中常用的功能,然而現(xiàn)有 react 懶加載組件庫(kù),用著都不是很爽了 ?。概括一下有如下幾點(diǎn): 沒(méi)有只針對(duì) image 懶加載組件。多...
閱讀 1867·2023-04-25 19:51
閱讀 1168·2021-11-15 11:43
閱讀 4529·2021-11-02 14:40
閱讀 1999·2021-10-11 10:59
閱讀 1338·2021-09-22 15:05
閱讀 1027·2021-09-09 09:32
閱讀 648·2019-08-30 15:56
閱讀 549·2019-08-30 15:52