1. 程式人生 > >img.onload 實現圖片預載入方法

img.onload 實現圖片預載入方法

例子:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
    <title></title>
    <script type="text/javascript" src="jQuery.js"></script>

</head>
<body>
    <div class="box">
       <div> 1111</div>
    </div>
<script type="text/javascript">
function loadImage(url,callback) {     
    var img =new Image();
    img.onload =function(){
        img.onload =null;
        callback(img);
    }
    img.src = url; 
}

function call(img){
    $(img).appendTo('.box');
}
// loadImage('http://www.appelsiini.net/projects/lazyload/img/viper_1.jpg',call);
loadImage('http://www.appelsiini.net/projects/lazyload/img/bmw_m1_hood.jpg',call);

    </script>
</body>
</html>

文章講解:

function loadImage(url, callback) {     
    
var img =
new Image(); //建立一個Image物件,實現圖片的預下載     
    img.src = url;     
        
    
if (img.complete) { // 如果圖片已經存在於瀏覽器快取,直接呼叫回撥函式     
        callback(img);     
        
return// 直接返回,不用再處理onload事件     
    }     
    
   
img.onload =
function () { //圖片下載完畢時非同步呼叫callback函式。     

    
     callback(img);


  };  



   
};     



在網上搜索了一下相關文章,大體上都是這個思路。
這個方法功能是ok的,但是有一些隱患。
1  建立了一個臨時匿名函式來作為圖片的onload事件處理函式,形成了閉包。
相 信大家都看到過ie下的記憶體洩漏模式的文章,其中有一個模式就是迴圈引用,而閉包就有儲存外部執行環境的能力(依賴於作用域鏈的實現),所以 img.onload這個函式內部又儲存了對img的引用,這樣就形成了迴圈引用,導致記憶體洩漏。(這種模式的記憶體洩漏只存在低版本的ie6中,打過補丁 的ie6以及高版本的ie都解決了迴圈引用導致的記憶體洩漏問題)。
2  只考慮了靜態圖片的載入,忽略了gif等動態圖片,這些動態圖片可能會多次觸發onload。

要解決上面兩個問題很簡單,其實很簡單,程式碼如下:

img.onload =
function () { //圖片下載完畢時非同步呼叫callback函式。         
    img.onload =
null;    
    callback(img);     
};  


這樣既能解決記憶體洩漏的問題,又能避免動態圖片的事件多次觸發問題。
在 一些相關博文中,也有人注意到了要把img.onload 設定為null,只不過時機不對,大部分文章都是在callback執行以後,才將img.onload設定為null,這樣雖然能解決迴圈引用的問題, 但是對於動態圖片來說,如果callback執行比較耗時的話,還是有多次觸發的隱患的。
隱患經過上面的修改後,就消除了,但是這個程式碼還有優化的餘地:

if (img.complete) { // 如果圖片已經存在於瀏覽器快取,直接呼叫回撥函式     
      callback(img);     
      
return// 直接返回,不用再處理onload事件     
}    

關於這段程式碼,看相關博文裡的敘述,原因如下:

經過對多個瀏覽器版本的測試,發現ie、opera下,當圖片載入過一次以後,如果再有對該圖片的請求時,由於瀏覽器已經快取住這張圖
了,不會再發起一次新的請求,而是直接從快取中載入過來。對於 firefox和safari,它們試圖使這兩種載入方式對使用者透明,同樣
會引起圖片的onload事件,而ie和opera則忽略了這種同一性,不會引起圖片的onload事件,因此上邊的程式碼在它們裡邊不能得以實
現效果。

確 實,在ie,opera下,對於快取圖片的初始狀態,與firefox和safari,chrome下是不一樣的(有興趣的話,可以在不同瀏覽器下,測試 一下在給img的src賦值快取圖片的url之前,img的狀態),但是對onload事件的觸發,卻是一致的,不管是什麼瀏覽器。產生這個問題的根本原 因在於,img的src賦值與 onload事件的繫結,順序不對(在ie和opera下,先賦值src,再賦值onload,因為是快取圖片,就錯過了onload事件的觸發)。應該 先繫結onload事件,然後再給src賦值,程式碼如下:

function loadImage(url, callback) {     
    
var img =
new Image(); //建立一個Image物件,實現圖片的預下載     
    img.onload =
function(){
        img.onload 
=
null;
        callback(img);
    }
    img.src 
= url; 
}




這樣記憶體洩漏,動態圖片的載入問題都得到了解決,而且也以統一的方式,實現了callback的呼叫。

相關推薦

img.onload 實現圖片載入方法

例子: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <h

使用原生JavaScript實現圖片載入,方法簡單程式碼少

//===結構程式碼   <img  src="./loading.gif" /> //===首先在頁面顯示的是一個loading圖  當請求返回的時候把返回的圖片替換上去 //====js程式碼 let imgArr = [   './beautiful.jpg',   './beautiful

js實現圖片載入 imgpreLoad.js

// 更新:// 05.27: 1、保證回撥執行順序:error > ready > load;2、回撥函式this指向img本身// 04-02: 1、增加圖片完全載入後的回撥 2、提高

簡單的實現圖片覽, 通過原生ajax以及 jQuery兩種方法實現圖片覽,有更好的辦法可以留言喔................

XML HP OS image end php代碼 append sda ext 1.原生寫ajax實現圖片預覽:   結構:     <input type="file">       <img src="" > JavaScri

圖片載入實現

圖片預載入說白了就是將所有所需的圖片提前請求載入到本地,這樣後面在需要用到時就直接從快取取圖片 。圖片預載入的原理很簡單:new Image(),然後使用onload方法回撥預載入完成事件,當瀏覽器把圖片下載到本地後,之後同樣的src就直接使用快取。 無序載入

圖片載入的三個方法

利用CSS、JavaScript及Ajax實現圖片預載入的三大方法   預載入圖片是提高使用者體驗的一個很好方法。圖片預先載入到瀏覽器中,訪問者便可順利地在你的網站上衝浪,並享受到極快的載入速度。 這對圖片畫廊及圖片佔據很大比例的網站來說十分有利,它保證了圖片快速、無縫地釋出,也可幫助使用者

jQuery實現圖片載入的兩種方法記錄

記錄一 整體思路: 設定個data-original(自定義一個屬性)來存放真實地址 當滾動頁面時,檢查所有的img標籤,看是否出現在視野中,如果已經出現在了視野中,那繼續再進行判斷,看其是否已經被載入過了,如果還沒有被載入過,那就進行載入。 程式碼: laz

圖片載入圖片載入(緩載)的區別與實現

<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>原生Js圖片延遲載入</title> <style type="text/

javascript實現圖片載入載入

所謂懶載入就是通過某些特定的條件,然後再給圖片的src賦值,常見的懶載入方式有點選載入和滾動載入。 如果是點選載入,那麼一般是通過點選事件。例如: 然後新增點選事件: 效果如下: 如

虛擬代理實現圖片加載

cti plus urn reload color load 會有 charset creat 1. 代碼如下 <!doctype html> <html lang="en"> <head> <meta chars

通過createObjectURL實現圖片

files val 圖片 文件 his 瀏覽器緩存 targe urn void 實現原理:通過createObjectURL 創建一個臨時指向某地址的二進制對象。 過程:點擊觸發隱藏的 input file 的點擊事件,使用createObjectURL讀取 fil

網頁中圖片載入的原理

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

前端接收資料流實現圖片覽效果--ajax 請求二進位制流 圖片 檔案 XMLHttpRequest 請求並處理二進位制流資料 之最佳實踐

本文為轉載文章 原文連結:https://www.cnblogs.com/cdemo/p/5225848.html 首先要謝謝這位大神的無私貢獻!解決了我的問題也完美表達了我當時的心路歷程 ajax 請求二進位制流 圖片 檔案 XMLHttpRequest 請求並處理二進位制流資料 之最佳實踐

如何結合外掛 vue-lazyload 來簡單實現圖片載入

外掛地址:https://www.npmjs.com/package/vue-lazyload; 一、使用場景: 在專案中有很多條數的資訊,且圖片很多的時候,不需要一次把整個頁面的圖片都載入完,而是在滾動到出現在螢幕才去載入該圖片的時候就可以用這個外掛。 二、簡單使用步驟: 1. 在專案裡面 npm

css圖片載入

css  /* 預載入圖片,掛在body上 */ .preload-img:after{ content:""; background: url(../images/new/full_bg2.jpg) no-repeat -10000px -1000px; }

小程式實現圖片覽和長按儲存本地

主要是用到這個api wx.previewImage({ current: , // 當前顯示圖片的http連結 urls: [] // 需要預覽的圖片http連結列表 }) 頁面.wxml <image src="{{invoice.viewPath}}" dat

Vue 實現圖片覽、裁剪並獲取被裁剪區域的base64(無元件)

前言     最近公司專案需要用到圖片裁剪技術,便著手寫了一個,可以說是用Vue實現的原生裁剪,畢竟也只是去操作dom,不過vue有個黑魔法,ref屬性,使用的方法和原生dom一模一樣但是更節省dom操作時的消耗 裁剪思路 這邊大致介紹一下裁剪圖片的思路

input file 實現圖片覽效果

引入jq檔案 <script src="https://cdn.bootcss.com/jquery/2.1.1/jquery.js"></script> js程式碼 <script> $(function(){

vue-lazyload實現圖片載入的方式

1、安裝vue-lazyload npm install --save vue-lazyload 2、在main.js中引入並申明使用 (1)引入 import VueLazyload from 'vue-lazyload' (2)申明使用 Vue.use(Vue

三種定義JQuery載入方法及JQuery選擇器

jQuery頁面預載入方法: jQuery(document).ready(function(){     alert("222"); }); jQuery(function(){     alert("33