[轉]你不知道的<img>標簽

< img> 標簽是頁面上最為重要的元素之一。很難想象一個頁面上沒有圖片的樣子,這樣的頁面效果將會大打折扣。


任何一個前端工程師想必對< img>標簽都非常熟悉了,畢竟經常和它打交道嘛。但你真的對它完全了解嗎?如果你能準確無誤地回答出以下幾個關于< img>的問題,那么恭喜你,本文你可以不再往下看了,或者說你可以用省視的目光來核對本文。

  • 問題1:如果在一個頁面上插入< img>標簽,有哪些屬性是必需的?
  • 問題2:< img>標簽在HTML和XHTML中有什么區別?
  • 問題3:在一個頁面上插入< img>標簽,為什么說最好要使用height和width屬性?
  • 問題4:< img>標簽的onload/onerror/onabort事件,在什么情況下會被觸發?
  • 問題5:我們一般知道,當一個圖片請求返回404時,會觸發onerror事件,那當圖片請求返回302時,會觸發onerror事件嗎?304呢?403呢?500呢?請求超時呢?甚至說當返回200,但內容并非是圖片時,也會觸發onerror么?
  • 問題6:圖片觸發onerror事件時,能使用javascript獲取到圖片請求的響應代碼么?
  • 問題7:我們一般知道,< img>標簽可以用來發起跨域請求,你能手寫出一段正確使用< img>發起跨域請求的javascript代碼么?
  • 問題8:用戶是可以設置瀏覽器不顯示圖片的,尤其是在移動設備上,用戶為了節省流量,往往會進行那么,如何獲知用戶是否禁止瀏覽圖片呢?

問題1:如果在一個頁面上插入< img>標簽,有哪些屬性是必需的?

答案是src和alt。
實例:(本實例摘自W3school: http://www.w3school.com.cn
< img src=" http://www.w3school.com.cn/i/eg_tulip.jpg" alt="上海鮮花港 - 郁金香" />

src屬性規定了顯示圖像的URL,瀏覽器會對該URL發起Http Get請求。
alt屬性則規定了圖像的替代文本,在圖像無法顯示或者用戶禁用圖像顯示時,代替圖像顯示在瀏覽器中的內容。如下圖:



與src屬性相比較,alt屬性更容易被設計人員和開發人員所忽視,事實上,在筆者撰寫本文時,即使在國內一些大型門戶網站首頁上(例如新浪、搜狐),我們也可以找到許多沒有alt屬性的< img>標簽。但筆者強烈推薦在文檔的每個圖像中都使用這個屬性,這樣即使圖像無法顯示,用戶還是可以看到的一些相關信息,從而大大提高了頁面的用戶友好性。

問題2:< img>標簽在HTML和XHTML中有什么區別?

(答案摘自W3school: http://www.w3school.com.cn
在 HTML 中,< img> 標簽沒有結束標簽。例如:
< img src=" http://www.w3school.com.cn/i/eg_tulip.jpg" alt="上海鮮花港 - 郁金香" >

在 XHTML 中,< img> 標簽必須被正確地關閉。
< img src=" http://www.w3school.com.cn/i/eg_tulip.jpg" alt="上海鮮花港 - 郁金香" />

在 HTML 4.01 中,不推薦使用 image 元素的 "align"、"border"、"hspace" 以及 "vspace" 屬性。在 XHTML 1.0 Strict DTD 中,不支持 image 元素的 "align"、"border"、"hspace" 以及 "vspace" 屬性。

問題3:在一個頁面上插入< img>標簽,為什么說最好要使用height和width屬性?

您在瀏覽網頁的時候,可能會遇到這種情況:隨著頁面中的圖像加載并成功顯示,頁面上的內容會隨之發生不規律的移動,影響您的閱讀。這種情況就是因為頁面上的圖像沒有定義height和width屬性而導致的。

如果沒有定義圖片的height和width屬性,那么瀏覽器為了能夠顯示每一個加載的圖像,它需要先下載圖像,然后解析出圖像的高度和寬度,并在顯示窗口留出相應的屏幕空間,這樣就會導致瀏覽器不斷地重新計算/調整頁面的布局,這可能會延遲文檔的顯示,并導致頁面重繪。

因此,筆者建議使用< img>的 height 和 width 屬性來指定圖像的尺寸。這樣的話,瀏覽器在下載圖像之前就為其預留出了空間,從而可以加速文檔的顯示,還可以避免文檔內容的移動而引起頁面重繪。

但是,需要注意的是:不要通過 height 和 width 屬性來縮放圖像。如果通過 height 和 width 屬性來縮小圖像,那么用戶就必須下載大容量的圖像(即使圖像在頁面上看上去很小)。正確的做法是,在網頁上使用圖像之前,應該通過軟件把圖像處理為合適的尺寸。當然,這個準則在實際應用中也有例外,例如筆者就認為,小比例的圖像縮放應該是允許的,此外,如果頁面上需要加載同一張圖像的不同尺寸的顯示,因為瀏覽器對同一個圖像只會請求一次,因此此時就建議使用height 和 width 屬性來縮放圖像。

問題4:< img>標簽的onload/onerror/onabort事件,在什么情況下會被觸發?

onload: 事件會在圖像加載完成后立即發生。

onerror: 事件會在文檔或圖像加載過程中發生錯誤時被觸發。

onabort: 事件會在圖像加載被中斷時發生。例如用戶單擊了瀏覽器的Stop按鈕,或者在圖像下載的過程中。

上面的三句話雖然看起來很簡單,但實際上有許多細節需要進一步的研究,尤其是onload和onerror事件。這些細節的問題,將在問題5中提出。

問題5:我們一般知道,當一個圖片請求返回404時,會觸發onerror事件,那當圖片請求返回302時,會觸發onerror事件嗎?304呢?403呢?500呢?請求超時呢?甚至說當返回200,但內容并非是圖片時,也會觸發onerror么?

這些問題需要動手做個試驗。試驗的結果如下表所示:

圖片請求 觸發的事件類型 IE FireFox Chrome
返回404 onerror
返回302,并且跳轉地址為一個正常的圖片 onload 所觸發的事件類型與原始的請求無關,而是與跳轉地址相關。
返回304,并且緩存生效 onload 但也要注意,如果緩存不存在,僅僅是單純地返回304,依然會觸發onerror
返回403 onerror
返回500 onerror
請求超時 onerror 返回504
返回200,但返回的內容并非圖片 onerror
問題6:圖片觸發onerror事件時,能使用javascript獲取到圖片請求的響應代碼么?

很遺憾,目前瀏覽器廠商尚未提供相關的接口。

問題7:我們一般知道,< img>標簽可以用來發起跨域請求,你能手寫出一段正確使用< img>發起跨域請求的javascript函數么?

這個問題看起來很簡單,或許你很快的就寫出了以下代碼:

function setImageSrc() {
    var i = new Image();
    i.src = "http://.../1.gif";
    i.onload = function() {
        // do sth.
    };

    i.onerror = function() {
        // do sth.
    }

    i.onabort = function() {
        // do sth.
    }
}

代碼中新建了一個image對象,并綁定了onload, onerror, onabort三個事件處理函數。

但實際上,上述代碼存在幾個問題,你能看出幾個呢?

  1.   屬性src賦值操作應該在事件綁定之后:否則,有可能出現圖片已經加載完畢、但事件綁定尚未完成的情況。例如,在上述代碼片段中,如果在第三行和第四行之間增加一句alert(1),就能重現這種情況。
    
  2.   在IE6中,上述事件綁定代碼會形成一個循環引用——Image對象的onload屬性引用了一個匿名函數對象,而匿名函數通過其作用域鏈引用會Image對象,這種循環引用會在IE6中導致內存泄露。因此,在onload的匿名函數中,應該解除循環引用,正確的代碼類似于:
    
i.onload = function() {
    // do sth.
    
    i.onload = null;
    i = null;
}
  1.   在IE6中,如果圖片是多幀的gif,會觸發多次的onload事件。因此,為避免這種情況,也需要在onload事件處理函數中解除事件函數:
    
i.onload = function() {
    // do sth.
 
    i.onload = null;
    i = null;
}
問題8:用戶是可以設置瀏覽器不顯示圖片的,尤其是在移動設備上,用戶為了節省流量,往往會禁止圖片顯示。那么,如何獲知用戶是否禁止瀏覽圖片呢?

注:該問題的解決方案來源于 http://stackoverflow.com/questions/8379156/how-to-detect-if-images-are-disabled-in-browser,筆者對其中的原理和代碼bug做了相應的解讀和修復。

在Firefox和Chrome中,可以使用Image對象的complete屬性來解決此問題:設置Image對象的src屬性,以請求一個不存在的圖片,當瀏覽器禁止顯示圖片時,Image對象的complete屬性為true,否則為false。

在Opera中,也可以使用Image對象的complete屬性,但它與Firefox和Chrome的不同,設置Image的src后,在onload之前,它一直顯示為false。但我們可以將圖片的src設置為一個特殊的值:img.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw=="; 這樣,當Opera禁止顯示圖片時,Image的complete屬性為false,否則為true。

而在IE中,Image的complete屬性會一直為false。因此,但我們注意到,當IE禁止顯示圖片時,是不會觸發Image對象的onload/onerror/onabort事件的。針對該特性,我們使用setTimeout函數,當在一定的時間內沒有檢測onload/onerror/onabort事件的發生,則認為瀏覽器禁止顯示圖片。

參考文章:http://www.cnblogs.com/hencehong/archive/2012/10/06/something_interesting_about_image.html

————
前端·小h
紙上得來終覺淺,絕知此事要躬行

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,786評論 6 534
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,656評論 3 419
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,697評論 0 379
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,098評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,855評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,254評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,322評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,473評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,014評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,833評論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,016評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,568評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,273評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,680評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,946評論 1 288
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,730評論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,006評論 2 374

推薦閱讀更多精彩內容

  • HTML標簽解釋大全 一、HTML標記 標簽:!DOCTYPE 說明:指定了 HTML 文檔遵循的文檔類型定義(D...
    米塔塔閱讀 3,294評論 1 41
  • Yahoo!的Exceptional Performance團隊為改善Web性能帶來最佳實踐。他們為此進行了一系列...
    拉風的老衲閱讀 1,865評論 0 1
  • 轉載請聲明 原文鏈接 關注公眾號獲取更多資訊 這篇文章主要總結H5的一些新增的功能以及一些基礎歸納,這里只是一個提...
    前端進階之旅閱讀 9,091評論 22 225
  • 1、簡介 現需在一個html頁面中顯示一張圖片,這張圖片的地址是通過GET方式從地址欄中傳入的。但是如果圖片損壞或...
    半吊子伯爵閱讀 392評論 0 1
  • 網絡發達,信息不對稱的情形大為改善。想要習得新技能,例如美妝,美體,美膚等,在網上都有教程。 只要自己用心學習...
    斐麗希婭閱讀 139評論 2 1