目錄javascript
Lazy Load也叫惰性加載,延遲加載,顧名思義,就是在圖片未到達可視區域時,不加載圖片,咱們經常在不少的優秀網站上看到相似的例子,例如迅雷、土豆、優酷等,因爲一個網頁的圖片很是多,一次性加載增長服務器壓力,並且用戶未必會拉到底部,浪費用戶流量,Lazy Load採用按需加載,更快的加載速度從而達到優化網頁的目的。css
使用方法:html
<script src="jquery.js" type="text/javascript"></script>
<script src="jquery.lazyload.js" type="text/javascript"></script>
<img class="lazy" data-original="img/example.jpg" width="640" height="480">
$(function(){ $("img.lazy").lazyload(); });
注意:你必須給圖片設置一個height和width,或者在CSS中定義,不然可能會影響到圖片的顯示。前端
$("img.lazy").lazyload({ threshold :200 });
事件綁定加載的方式:event,你可使用jQuery的事件,例如「click」、「mouseover」,或者你也能夠自定義事件,默認等待用戶滾動,圖片出如今可視區域。下面是使用click:java
$("img.lazy").lazyload({event:"click"});
顯示效果:effect,默認使用show(),你可使用fadeIn(逐漸出現)方式,代碼以下:jquery
$("img.lazy").lazyload({ effect :"fadeIn" });
對於禁用javascript的瀏覽器則要加上noscript內容:css3
<img class="lazy" data-original="img/example.jpg" width="640" heigh="480"> <noscript><img src="img/example.jpg" alt="jQuery圖片預加載(延遲加載)插件Lazy Load" width="640" heigh="480"></noscript>
圖片限定在某個容器內:container,你能夠經過限定某個容器內容的圖片纔會生效,代碼以下:web
#container {
height:600px;
overflow: scroll;
}
$("img.lazy").lazyload({ container: $("#container") });
原文連接: jQuery圖片預加載(延遲加載)插件Lazy Loadajax
在瀏覽器渲染圖片的時候, 它得到圖片的一片區域的時候, 就已經爲這張圖片預留了一片空白的區域來填充圖片, 這就是預加載得到圖片尺寸最原始的使用方法.數組
有時候會加載一些在當前頁面沒有用到的圖片,是爲了提早加載到緩存裏,這樣後面的頁面就能夠直接從緩存讀取了。
加載大圖的時候,咱們能夠先顯示模糊的縮略圖,等到大圖加載完了,再把縮略圖替換掉,這樣填補了圖片加載期間的空白時間。
image也有onload和onerror事件,分別是加載完後和加載失敗時執行。
Image對象是專門用於處理圖片加載的,就至關於內存中的img標籤。
圖片預加載案例:鼠標移入一張圖片時,換成另外一張圖片,移出時換回原來的圖片。正常作法是,鼠標移入的時候,改變圖片的src,但這時就要去加載圖片了,會等待一段時間,這樣體驗很差。預加載的作法是,在頁面加載完,鼠標移入以前就經過Image對象把圖片加載進緩存了,這樣鼠標移入的時候直接從緩存裏讀取了,速度很快。
if(document.images){ var img = new Image(); img.src = "img/example.jpg"; }
//實現圖片的預加載 function preloadImg(srcArr){ if(srcArr instanceof Array){ for(var i=0; i<srcArr.length; i++){ var oImg = new Image(); oImg.src = srcArr[i]; } } } //預加載圖片 preloadImg(['image/example.jpg']); //參數是一個url數組
function getPreloadImgAttr(url,callback){ var oImg = new Image(); //建立一個Image對象,實現圖片的預加載 oImg.src = url; // 看下一節,其實應當先進行onload的綁定,再賦值給src if(oImg.complete){ //若是圖片已經存在於瀏覽器緩存,直接調用回調函數 callback.call(oImg); return; //直接返回,再也不處理onload事件 } oImg.onload = function(){ //圖片下載完畢時異步調用callback函數 callback.call(oImg); }; } getPreloadImgAttr('image/example.jpg',function(){ console.log(this.width, this.height); });
建立了一個臨時匿名函數來做爲圖片的onload事件處理函數,造成了閉包。
相信你們都看到過ie下的內存泄漏模式的文章,其中有一個模式就是循環引用,而閉包就有保存外部運行環境的能力(依賴於做用域鏈的實現),因此img.onload這個函數內部又保存了對img的引用,這樣就造成了循環引用,致使內存泄漏。(這種模式的內存泄漏只存在低版本的ie6中,打過補丁的ie6以及高版本的ie都解決了循環引用致使的內存泄漏問題)。
只考慮了靜態圖片的加載,忽略了gif等動態圖片,這些動態圖片可能會屢次觸發onload。
function loadImage(url, callback) { var img = new Image(); //建立一個Image對象,實現圖片的預下載 img.onload = function(){ img.onload = null; callback(img); } img.src = url; }
這樣內存泄漏,動態圖片的加載問題都獲得瞭解決,並且也以統一的方式,實現了callback的調用。
關於這個方法, 有個疑問是緩存的問題, 在原文裏也給出了一些解釋
通過對多個瀏覽器版本的測試,發現ie、opera下,當圖片加載過一次之後,若是再有對該圖片的請求時,因爲瀏覽器已經緩存住這張圖片了,不會再發起一次新的請求,而是直接從緩存中加載過來。對於 firefox和safari,它們試圖使這兩種加載方式對用戶透明,一樣會引發圖片的onload事件,而ie和opera則忽略了這種同一性,不會引發圖片的onload事件,所以上邊的代碼在它們裏邊不能得以實現效果。
但總體來說,仍然應該先進行onload事件的綁定, 再賦值src
參考:[前端] 圖片預加載及獲取屬性 關於圖片的預加載,你所不知道的
這個概念就是寫一個CSS樣式設置一批背景圖片,而後將其隱藏,這樣你就看不到那些圖片了。那些背景圖片就是你想預載的圖片。
#preload-01 { background: url(http://domain.tld/image-01.png) no-repeat -9999px -9999px; } #preload-02 { background: url(http://domain.tld/image-02.png) no-repeat -9999px -9999px; } #preload-03 { background: url(http://domain.tld/image-03.png) no-repeat -9999px -9999px; }
這裏爲了隱藏這些圖片, 使用了位置設置爲極大的負值的方法. 還能夠直接設置 { width: 0; height: 0; display: none};
該方法雖然高效,但仍有改進餘地。使用該法加載的圖片會同頁面的其餘內容一塊兒加載,增長了頁面的總體加載時間。爲了解決這個問題,咱們增長了一些JavaScript代碼,來推遲預加載的時間,直到頁面加載完畢。代碼以下:
// better image preloading @ <a href="http://perishablepress.com/press/2009/12/28/3-ways-preload-images-css-javascript-ajax/">http://perishablepress.com/press/2009/12/28/3-ways-preload-images-css-javascript-ajax/</a> function preloader() { if (document.getElementById) { document.getElementById("preload-01").style.background = "url(http://domain.tld/image-01.png) no-repeat -9999px -9999px"; document.getElementById("preload-02").style.background = "url(http://domain.tld/image-02.png) no-repeat -9999px -9999px"; document.getElementById("preload-03").style.background = "url(http://domain.tld/image-03.png) no-repeat -9999px -9999px"; } } function addLoadEvent(func) { var oldonload = window.onload; if (typeof window.onload != 'function') { window.onload = func; } else { window.onload = function() { if (oldonload) { oldonload(); } func(); } } } addLoadEvent(preloader);
在該腳本的第一部分,咱們獲取使用類選擇器的元素,併爲其設置了background屬性,以預加載不一樣的圖片。
該腳本的第二部分,咱們使用addLoadEvent()函數來延遲preloader()函數的加載時間,直到頁面加載完畢。
若是JavaScript沒法在用戶的瀏覽器中正常運行,會發生什麼?很簡單,圖片不會被預加載,當頁面調用圖片時,正常顯示便可。
參考: 純CSS圖片預加載 Javascript圖片預加載詳解
該方法利用DOM,不只僅預加載圖片,還會預加載CSS、JavaScript等相關的東西。使用Ajax,比直接使用JavaScript,優越之處在於JavaScript和CSS的加載不會影響到當前頁面。該方法簡潔、高效。
window.onload = function() { setTimeout(function() { // XHR to request a JS and a CSS var xhr = new XMLHttpRequest(); xhr.open('GET', 'http://domain.tld/preload.js'); xhr.send(''); xhr = new XMLHttpRequest(); xhr.open('GET', 'http://domain.tld/preload.css'); xhr.send(''); // preload image new Image().src = "http://domain.tld/preload.png"; }, 1000); };
上面代碼預加載了「preload.js」、「preload.css」和「preload.png」。1000毫秒的超時是爲了防止腳本掛起,而致使正常頁面出現功能問題。
與之相比, 若是用js的話, 要實現以上加載過程則會應用到頁面上. 實現以下
window.onload = function() { setTimeout(function() { // reference to <head> var head = document.getElementsByTagName('head')[0]; // a new CSS var css = document.createElement('link'); css.type = "text/css"; css.rel = "stylesheet"; css.href = "http://domain.tld/preload.css"; // a new JS var js = document.createElement("script"); js.type = "text/javascript"; js.src = "http://domain.tld/preload.js"; // preload JS and CSS head.appendChild(css); head.appendChild(js); // preload image new Image().src = "http://domain.tld/preload.png"; }, 1000); };
這裏,咱們經過DOM建立三個元素來實現三個文件的預加載。正如上面提到的那樣,使用Ajax,加載文件不會應用到加載頁面上。從這點上看,Ajax方法優越於JavaScript。