[轉(zhuǎn)]你不知道的<img>標(biāo)簽

< img> 標(biāo)簽是頁面上最為重要的元素之一臀防。很難想象一個(gè)頁面上沒有圖片的樣子眠菇,這樣的頁面效果將會(huì)大打折扣。


任何一個(gè)前端工程師想必對(duì)< img>標(biāo)簽都非常熟悉了袱衷,畢竟經(jīng)常和它打交道嘛捎废。但你真的對(duì)它完全了解嗎?如果你能準(zhǔn)確無誤地回答出以下幾個(gè)關(guān)于< img>的問題致燥,那么恭喜你登疗,本文你可以不再往下看了,或者說你可以用省視的目光來核對(duì)本文嫌蚤。

  • 問題1:如果在一個(gè)頁面上插入< img>標(biāo)簽辐益,有哪些屬性是必需的?
  • 問題2:< img>標(biāo)簽在HTML和XHTML中有什么區(qū)別脱吱?
  • 問題3:在一個(gè)頁面上插入< img>標(biāo)簽智政,為什么說最好要使用height和width屬性?
  • 問題4:< img>標(biāo)簽的onload/onerror/onabort事件箱蝠,在什么情況下會(huì)被觸發(fā)续捂?
  • 問題5:我們一般知道,當(dāng)一個(gè)圖片請(qǐng)求返回404時(shí)宦搬,會(huì)觸發(fā)onerror事件牙瓢,那當(dāng)圖片請(qǐng)求返回302時(shí),會(huì)觸發(fā)onerror事件嗎间校?304呢矾克?403呢?500呢憔足?請(qǐng)求超時(shí)呢胁附?甚至說當(dāng)返回200,但內(nèi)容并非是圖片時(shí)四瘫,也會(huì)觸發(fā)onerror么汉嗽?
  • 問題6:圖片觸發(fā)onerror事件時(shí),能使用javascript獲取到圖片請(qǐng)求的響應(yīng)代碼么找蜜?
  • 問題7:我們一般知道饼暑,< img>標(biāo)簽可以用來發(fā)起跨域請(qǐng)求,你能手寫出一段正確使用< img>發(fā)起跨域請(qǐng)求的javascript代碼么?
  • 問題8:用戶是可以設(shè)置瀏覽器不顯示圖片的弓叛,尤其是在移動(dòng)設(shè)備上彰居,用戶為了節(jié)省流量,往往會(huì)進(jìn)行那么撰筷,如何獲知用戶是否禁止瀏覽圖片呢陈惰?

問題1:如果在一個(gè)頁面上插入< img>標(biāo)簽,有哪些屬性是必需的毕籽?

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

src屬性規(guī)定了顯示圖像的URL,瀏覽器會(huì)對(duì)該URL發(fā)起Http Get請(qǐng)求关筒。
alt屬性則規(guī)定了圖像的替代文本溶握,在圖像無法顯示或者用戶禁用圖像顯示時(shí),代替圖像顯示在瀏覽器中的內(nèi)容蒸播。如下圖:



與src屬性相比較睡榆,alt屬性更容易被設(shè)計(jì)人員和開發(fā)人員所忽視,事實(shí)上袍榆,在筆者撰寫本文時(shí)胀屿,即使在國內(nèi)一些大型門戶網(wǎng)站首頁上(例如新浪、搜狐)包雀,我們也可以找到許多沒有alt屬性的< img>標(biāo)簽宿崭。但筆者強(qiáng)烈推薦在文檔的每個(gè)圖像中都使用這個(gè)屬性,這樣即使圖像無法顯示馏艾,用戶還是可以看到的一些相關(guān)信息劳曹,從而大大提高了頁面的用戶友好性。

問題2:< img>標(biāo)簽在HTML和XHTML中有什么區(qū)別琅摩?

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

在 XHTML 中房资,< img> 標(biāo)簽必須被正確地關(guān)閉蜕劝。
< 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:在一個(gè)頁面上插入< img>標(biāo)簽唉俗,為什么說最好要使用height和width屬性嗤朴?

您在瀏覽網(wǎng)頁的時(shí)候,可能會(huì)遇到這種情況:隨著頁面中的圖像加載并成功顯示虫溜,頁面上的內(nèi)容會(huì)隨之發(fā)生不規(guī)律的移動(dòng)雹姊,影響您的閱讀。這種情況就是因?yàn)轫撁嫔系膱D像沒有定義height和width屬性而導(dǎo)致的衡楞。

如果沒有定義圖片的height和width屬性吱雏,那么瀏覽器為了能夠顯示每一個(gè)加載的圖像,它需要先下載圖像瘾境,然后解析出圖像的高度和寬度歧杏,并在顯示窗口留出相應(yīng)的屏幕空間,這樣就會(huì)導(dǎo)致瀏覽器不斷地重新計(jì)算/調(diào)整頁面的布局寄雀,這可能會(huì)延遲文檔的顯示得滤,并導(dǎo)致頁面重繪陨献。

因此盒犹,筆者建議使用< img>的 height 和 width 屬性來指定圖像的尺寸。這樣的話眨业,瀏覽器在下載圖像之前就為其預(yù)留出了空間急膀,從而可以加速文檔的顯示,還可以避免文檔內(nèi)容的移動(dòng)而引起頁面重繪龄捡。

但是卓嫂,需要注意的是:不要通過 height 和 width 屬性來縮放圖像。如果通過 height 和 width 屬性來縮小圖像聘殖,那么用戶就必須下載大容量的圖像(即使圖像在頁面上看上去很谐况ā)。正確的做法是奸腺,在網(wǎng)頁上使用圖像之前餐禁,應(yīng)該通過軟件把圖像處理為合適的尺寸。當(dāng)然突照,這個(gè)準(zhǔn)則在實(shí)際應(yīng)用中也有例外帮非,例如筆者就認(rèn)為,小比例的圖像縮放應(yīng)該是允許的讹蘑,此外末盔,如果頁面上需要加載同一張圖像的不同尺寸的顯示,因?yàn)闉g覽器對(duì)同一個(gè)圖像只會(huì)請(qǐng)求一次座慰,因此此時(shí)就建議使用height 和 width 屬性來縮放圖像陨舱。

問題4:< img>標(biāo)簽的onload/onerror/onabort事件,在什么情況下會(huì)被觸發(fā)版仔?

onload: 事件會(huì)在圖像加載完成后立即發(fā)生游盲。

onerror: 事件會(huì)在文檔或圖像加載過程中發(fā)生錯(cuò)誤時(shí)被觸發(fā)心剥。

onabort: 事件會(huì)在圖像加載被中斷時(shí)發(fā)生。例如用戶單擊了瀏覽器的Stop按鈕背桐,或者在圖像下載的過程中优烧。

上面的三句話雖然看起來很簡單,但實(shí)際上有許多細(xì)節(jié)需要進(jìn)一步的研究链峭,尤其是onload和onerror事件畦娄。這些細(xì)節(jié)的問題,將在問題5中提出弊仪。

問題5:我們一般知道熙卡,當(dāng)一個(gè)圖片請(qǐng)求返回404時(shí),會(huì)觸發(fā)onerror事件励饵,那當(dāng)圖片請(qǐng)求返回302時(shí)驳癌,會(huì)觸發(fā)onerror事件嗎?304呢役听?403呢颓鲜?500呢?請(qǐng)求超時(shí)呢典予?甚至說當(dāng)返回200甜滨,但內(nèi)容并非是圖片時(shí),也會(huì)觸發(fā)onerror么瘤袖?

這些問題需要?jiǎng)邮肿鰝€(gè)試驗(yàn)衣摩。試驗(yàn)的結(jié)果如下表所示:

圖片請(qǐng)求 觸發(fā)的事件類型 IE FireFox Chrome
返回404 onerror
返回302,并且跳轉(zhuǎn)地址為一個(gè)正常的圖片 onload 所觸發(fā)的事件類型與原始的請(qǐng)求無關(guān)捂敌,而是與跳轉(zhuǎn)地址相關(guān)艾扮。
返回304,并且緩存生效 onload 但也要注意占婉,如果緩存不存在泡嘴,僅僅是單純地返回304,依然會(huì)觸發(fā)onerror
返回403 onerror
返回500 onerror
請(qǐng)求超時(shí) onerror 返回504
返回200锐涯,但返回的內(nèi)容并非圖片 onerror
問題6:圖片觸發(fā)onerror事件時(shí)磕诊,能使用javascript獲取到圖片請(qǐng)求的響應(yīng)代碼么?

很遺憾纹腌,目前瀏覽器廠商尚未提供相關(guān)的接口霎终。

問題7:我們一般知道,< img>標(biāo)簽可以用來發(fā)起跨域請(qǐng)求升薯,你能手寫出一段正確使用< img>發(fā)起跨域請(qǐng)求的javascript函數(shù)么莱褒?

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

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.
    }
}

代碼中新建了一個(gè)image對(duì)象涎劈,并綁定了onload, onerror, onabort三個(gè)事件處理函數(shù)广凸。

但實(shí)際上阅茶,上述代碼存在幾個(gè)問題,你能看出幾個(gè)呢谅海?

  1.   屬性src賦值操作應(yīng)該在事件綁定之后:否則脸哀,有可能出現(xiàn)圖片已經(jīng)加載完畢、但事件綁定尚未完成的情況扭吁。例如撞蜂,在上述代碼片段中,如果在第三行和第四行之間增加一句alert(1)侥袜,就能重現(xiàn)這種情況蝌诡。
    
  2.   在IE6中,上述事件綁定代碼會(huì)形成一個(gè)循環(huán)引用——Image對(duì)象的onload屬性引用了一個(gè)匿名函數(shù)對(duì)象枫吧,而匿名函數(shù)通過其作用域鏈引用會(huì)Image對(duì)象浦旱,這種循環(huán)引用會(huì)在IE6中導(dǎo)致內(nèi)存泄露。因此九杂,在onload的匿名函數(shù)中颁湖,應(yīng)該解除循環(huán)引用,正確的代碼類似于:
    
i.onload = function() {
    // do sth.
    
    i.onload = null;
    i = null;
}
  1.   在IE6中尼酿,如果圖片是多幀的gif爷狈,會(huì)觸發(fā)多次的onload事件。因此裳擎,為避免這種情況,也需要在onload事件處理函數(shù)中解除事件函數(shù):
    
i.onload = function() {
    // do sth.
 
    i.onload = null;
    i = null;
}
問題8:用戶是可以設(shè)置瀏覽器不顯示圖片的思币,尤其是在移動(dòng)設(shè)備上鹿响,用戶為了節(jié)省流量,往往會(huì)禁止圖片顯示谷饿。那么惶我,如何獲知用戶是否禁止瀏覽圖片呢?

注:該問題的解決方案來源于 http://stackoverflow.com/questions/8379156/how-to-detect-if-images-are-disabled-in-browser博投,筆者對(duì)其中的原理和代碼bug做了相應(yīng)的解讀和修復(fù)绸贡。

在Firefox和Chrome中,可以使用Image對(duì)象的complete屬性來解決此問題:設(shè)置Image對(duì)象的src屬性毅哗,以請(qǐng)求一個(gè)不存在的圖片听怕,當(dāng)瀏覽器禁止顯示圖片時(shí),Image對(duì)象的complete屬性為true虑绵,否則為false尿瞭。

在Opera中,也可以使用Image對(duì)象的complete屬性翅睛,但它與Firefox和Chrome的不同声搁,設(shè)置Image的src后黑竞,在onload之前,它一直顯示為false疏旨。但我們可以將圖片的src設(shè)置為一個(gè)特殊的值:img.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw=="; 這樣很魂,當(dāng)Opera禁止顯示圖片時(shí),Image的complete屬性為false檐涝,否則為true莫换。

而在IE中,Image的complete屬性會(huì)一直為false骤铃。因此拉岁,但我們注意到,當(dāng)IE禁止顯示圖片時(shí)惰爬,是不會(huì)觸發(fā)Image對(duì)象的onload/onerror/onabort事件的喊暖。針對(duì)該特性,我們使用setTimeout函數(shù)撕瞧,當(dāng)在一定的時(shí)間內(nèi)沒有檢測onload/onerror/onabort事件的發(fā)生陵叽,則認(rèn)為瀏覽器禁止顯示圖片。

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

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末巩掺,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子页畦,更是在濱河造成了極大的恐慌胖替,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,378評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件豫缨,死亡現(xiàn)場離奇詭異独令,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)好芭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門燃箭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人舍败,你說我怎么就攤上這事招狸。” “怎么了邻薯?”我有些...
    開封第一講書人閱讀 152,702評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵裙戏,是天一觀的道長。 經(jīng)常有香客問我弛说,道長挽懦,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,259評(píng)論 1 279
  • 正文 為了忘掉前任木人,我火速辦了婚禮信柿,結(jié)果婚禮上冀偶,老公的妹妹穿的比我還像新娘。我一直安慰自己渔嚷,他們只是感情好进鸠,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評(píng)論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著形病,像睡著了一般客年。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上漠吻,一...
    開封第一講書人閱讀 49,036評(píng)論 1 285
  • 那天量瓜,我揣著相機(jī)與錄音,去河邊找鬼途乃。 笑死绍傲,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的耍共。 我是一名探鬼主播烫饼,決...
    沈念sama閱讀 38,349評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼试读!你這毒婦竟也來了杠纵?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,979評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤钩骇,失蹤者是張志新(化名)和其女友劉穎比藻,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體伊履,經(jīng)...
    沈念sama閱讀 43,469評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡韩容,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了唐瀑。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,059評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡插爹,死狀恐怖哄辣,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情赠尾,我是刑警寧澤力穗,帶...
    沈念sama閱讀 33,703評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站气嫁,受9級(jí)特大地震影響当窗,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜寸宵,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評(píng)論 3 307
  • 文/蒙蒙 一崖面、第九天 我趴在偏房一處隱蔽的房頂上張望元咙。 院中可真熱鬧,春花似錦巫员、人聲如沸庶香。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽赶掖。三九已至,卻和暖如春七扰,著一層夾襖步出監(jiān)牢的瞬間奢赂,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來泰國打工颈走, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留膳灶,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,501評(píng)論 2 354
  • 正文 我出身青樓疫鹊,卻偏偏與公主長得像袖瞻,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子拆吆,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • HTML標(biāo)簽解釋大全 一聋迎、HTML標(biāo)記 標(biāo)簽:!DOCTYPE 說明:指定了 HTML 文檔遵循的文檔類型定義(D...
    米塔塔閱讀 3,225評(píng)論 1 41
  • Yahoo!的Exceptional Performance團(tuán)隊(duì)為改善Web性能帶來最佳實(shí)踐。他們?yōu)榇诉M(jìn)行了一系列...
    拉風(fēng)的老衲閱讀 1,832評(píng)論 0 1
  • 轉(zhuǎn)載請(qǐng)聲明 原文鏈接 關(guān)注公眾號(hào)獲取更多資訊 這篇文章主要總結(jié)H5的一些新增的功能以及一些基礎(chǔ)歸納枣耀,這里只是一個(gè)提...
    程序員poetry閱讀 9,059評(píng)論 22 225
  • 1霉晕、簡介 現(xiàn)需在一個(gè)html頁面中顯示一張圖片,這張圖片的地址是通過GET方式從地址欄中傳入的捞奕。但是如果圖片損壞或...
    半吊子伯爵閱讀 349評(píng)論 0 1
  • 網(wǎng)絡(luò)發(fā)達(dá)颅围,信息不對(duì)稱的情形大為改善伟葫。想要習(xí)得新技能,例如美妝院促,美體筏养,美膚等,在網(wǎng)上都有教程常拓。 只要自己用心學(xué)習(xí)...
    斐麗希婭閱讀 123評(píng)論 2 1