new Image():創建圖片實體與載入單張圖片

Image 建構函式

Image (開頭大寫) 對於 JavaScript 來說,算是個特定的元素 (HTMLImageElement),而元素可使用 new 的方式透過建構式產生一個圖片實體。
console.log(Image) 透過開發者工具,可以看到回應內容是個 function Image()

prototype: HTMLImageElementPrototype 裡列出相的屬性與設定、還有 Image 方法等…在 Image 實體裡。

使用 new Image() 產生空的圖片實體

使用建構函式 new Image() 建立一個圖片實體出來,透過 console.log(new Image()); 會回應出 <img> 所新建的圖片實體出來。

展開後裡面就有圖片相關的屬性與方法,可以用來操作 DOM 元素上的圖片內容。

new Image()document.createElement('img') 的同異之處:
二個方式產生圖片實體的結果是一樣的,只是在支援使用上 document.createElement('img') 相容性會比較好 (IE8),與 new Image() 使用效能上 document.createElement('img') 也是比較優,生成 image 次數小於十萬次時,選擇 createElement (透過同時跑 for 迴圈就可比較出結果)。
次數比較少時, createElement 的效率更高,同時,這裡還提供了一種更高效的做法,就是使用頁面中的一個固定的 img 元素,同時在改變 img 的 src 的時候,設置 visibilityhidden,避免觸發 reflow 提高性能。

資料來源:
stackoverflow 英文討論:Is there a difference between new Image() and document.createElement('img')?
Javascript-new Image()document.createElement('img')之間有區別嗎
new Image() 與 document.createElement(‘img’) 的異同

使用 Image() 透過 src 取得圖片檔後,在 DOM 中產生圖片結構呈現畫面

MDN 說明 Image()
Image() 函數將會創建一個新的 HTMLImageElement 實例。
它的功能等價於 document.createElement('img')

width:圖片的寬度 (即 width 屬性).
height:圖片的高度 (即 height 屬性).

如果不透過 HTML 裡的 <body></body> 內插入 <img src=""> 的方式使用的話,可以透過 JavaScript 的 new Image() 建構式方式,在記憶體中插入一個新的圖片實體出來。

如果要直接透過 JavaScript 的 new Image() 方式建立出一筆 HTML 的元素出來,將所建的新的圖片透過賦值的方式,將路徑加到圖片的 .src 屬性上,就可以直接將元素加上圖片路徑,加上 src 的同時瀏覽器就會向伺服器發送請求,要求伺服器傳送對應的圖片檔案進來瀏覽器中,主機回應後接著就會進行傳送圖片檔的動作。

See the Pen 使用 Image() 透過 src 取得圖片檔後,在 DOM 中產生圖片結構呈現畫面 by Jimmy_Wu (@Jimmy_Wu) on CodePen.light

伺服器的圖片使用 unsplash 假圖服務 ,在網址 https://unsplash.it/ 的後方加上參數 3600/1800/ (圖片尺寸大小) 與 ?random=1 (亂數取得不同圖片)。


圖片載入情形

使用 .onload 與 .onerror 事件方法了解戴入情形

產生了圖片實體後透過 .src 將圖片路徑賦值,就可發送請求向伺服器要求傳送圖片檔案傳送,在傳送過程不一定會取得到圖片,也因此可以透過事件觸發回應的內容。

.onload 事件在圖片加載完成後立即執行
.onerror 載入期間發生錯誤時,由 error 會被 error 事件跟蹤到。

這裡以 Google 的圖片 https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png 為例來操作二個事件,其中錯誤的部份在網域名稱多加 111 讓遠端圖片取不到。

See the Pen 使用 Image() 的 .onload 與 .onerror 載入事件 by Jimmy_Wu (@Jimmy_Wu) on CodePen.light

以上程式碼運作的部份,當圖片載入的過程取不到圖片,就會觸發 .onerror 事件執行函式。
在開發者工具就會回應 "Error occurred while loading image" 的訊息。

.complete 判斷圖片是否載入完成 (布林值 true)

透過 .complete 的判斷式也是了解圖片載入的情形,配合著 if() else {} 分別針對該圖片做出對應的動作。
.complete 另外也可以理解成圖片是否載入成功到瀏覽器快取內,如果有圖片的話就會為 true

See the Pen 使用 Image() 的 .complete by Jimmy_Wu (@Jimmy_Wu) on CodePen.light

.complete 與 .onload 的混用

針對舊瀏覽器 IE 的圖片狀態 (相容性),透過 .complete 比較好操作結結果,IE 沒有觸發 .onload 事件,而是因為 IE 中加載緩衝區的速度太快,以至於沒有運行到 .onload 的時候,圖片已經被加載完畢了。因此,可以先告訴瀏覽器如何處理這張圖片,然後再製定這張圖片的來源。

另外透過三元運算子結合 .complete.onload 來使用。

See the Pen 使用 Image() 的 .complete by Jimmy_Wu (@Jimmy_Wu) on CodePen.light


一次產生多筆圖片的 .complete 與 .onload

非同步但同 src 圖片路徑的 .complete

圖片透過 .src 取得圖檔時是以非同步取得的。
這部份如果是在第一次戴入 google logo 圖片時會在使用 .complete 的判斷式下會第一次先判為 false,但如果要在短時間內將畫面重整後就會為 true
如果要將圖片產生到動元素,需要在重新執行畫面重整,才會顯示出來。
這裡產生的時間也都為同一時間。

See the Pen 使用 Image() 產生多圖 .complete – url 圖片路徑為同一張 by Jimmy_Wu (@Jimmy_Wu) on CodePen.light

非同步但不同 src 圖片路徑的 .complete 與 .onload

但如果讓圖片使用線上圖庫的 ?random= 參數,在每次執行時都會取到不同張的圖片,此時的 .complete 的判斷式永遠也都 false,無法在 .complete 下來操作圖片。
產生的時間會因為圖片戴入的前後有所不同。

See the Pen 使用 Image() 產生多圖 .complete – url 圖片路徑後加 unsplash 線上圖庫參數 ?random= ,永遠為 false by Jimmy_Wu (@Jimmy_Wu) on CodePen.light


參考資料