一、前言
我們一般使用方式為 <link type="text/css" rel="stylesheet" href="text.css"> 來引入外部層疊式樣式檔案,但LINK元素各屬性的具體含義、資源加載行為等方面卻了解不多,本文打算稍微深入一下。
由于内容較多,特設目錄一坨:
也許我們常常會看到一下兩種寫法


參考官網可知:
在 HTML 中,<link> 标簽沒有結束标簽。 在 XHTML 中,<link> 标簽必須被正确地關閉。
1. 屬性media ,指定該樣式應用到的顯示裝置(媒介類型),預設值為all,還有值screen(顯示器)和print(列印機)被浏覽器支援。另外還有一堆為成為事實标準的值。
2. HTML5屬性sizes ,用于指定網頁圖示高寬(格式: 高x寬 或預設值 any ),需要同時配置 rel="icons" ,示例:
3. 屬性type ,引入的資源MIME類型,注意:不規定必須為text/css。
由于disabled屬于标準屬性,是以可以通過點方式(property)和getAttribute方式(Attribute)對其進行操作。對于IE和Chrome,兩者是同步的。但對于FF來說兩者是分離的。
1. 對于靜态引入LINK元素,且通過Attribute方式設定disabled為true,由于Attribute和Property是分離的,此時FF下通過點方式操作的disabled依然為false(而IE、Chrome的則為true),而是否應用到元素渲染上則由點方式操作的disabled的值來決定,是以該方式在FF下依然會應用到元素渲染上,而在IE和Chrome上則不會應用到元素渲染上。
2. FF中需要靜态或動态引入LINK元素時,都必須等LINK元素被添加到渲染樹中後才可以通過點方式修改disabled,否則修改無效,disabled值一直為false。


僅Chrome在disabled為true時,不加載樣式檔案。其他浏覽器均依然繼續加載檔案資源。
由于FF下通過Attribute方式設定disabled為true,和在LINK元素未加入渲染樹前修改disabled為true均無效,是以僅FF下會觸發onload和onerror事件。其他浏覽器均不會觸發onload、onerror和onreadystatechange事件。
由于FF下存在上述特性,是以可以通過如下手段設定FF下的樣式的disabled為true。
首先需要了解的是CSS解析到底是什麼?
其實就是在成功加載樣式檔案後,将樣式檔案中的樣式添加到樣式表document.styleSheets中。而應用到元素渲染的樣式則為document.styleSheets的子集。
由于對于disabled為true的LINK元素,Chrome将不加載其樣式檔案,是以也無法将檔案中的樣式添加到document.styleSheets中;也隻有Chrome在将disabled屬性從false動态修改為true時,會從document.styleSheets中删除該樣式檔案的樣式。其他浏覽器隻要成功加載樣式檔案就會将其中的樣式添加到document.styleSheets中,無論disabled屬性值是什麼。
隻要LINK元素的點方式的disabled為true,那麼它所關聯的樣式規則均不生效。(FF則需要經過上述的特殊處理)
對于想通過樣式檔案書寫樣式規則,但又想通過document.styleSheets按需提取應用樣式的情況,由于Chrome采用直接不加載樣式檔案的處理方式,是以需要通過如下手段處理:
屬性rel用于規定目前文檔與被加載的資源之間的關系。
1. 定義網站收藏夾圖示


IE下rel必須為 shortcut icon ,而且圖示必須為 .ico格式 。而其他浏覽器的rel隻需寫為 icon ,圖示不一定需要使用 .ico格式 。
2. 定義蘋果桌面上的網站圖示
3. RSS位址和Pingback位址
動态建立元素一般有兩種方式,分别是document.createElement方法和innerHTML+firstChild。對于LINK元素,在IE9+和其他現代浏覽器中可使用innerHTML+firstChild方式建立LINK元素,而在IE5~8中則需要使用document.createElement方式建立。下面代碼為簡單的實作方式:


資源加載首先當然是确定資源位置的 href屬性 ,随之就是資源加載成功與否的 onload事件 和 onerror事件 ,對于IE5~8還多了一個 onreadystatechange事件 和與之相關的 readyState屬性
onload事件 ,當資源加載完成後觸發(注意:即使資源類型與LINK元素的type屬性值不符,隻要資源加載完成就會觸發onload事件)。
onerror事件 ,當找不到資源時會觸發(注意:IE5~11無論任何情況均不會觸發該事件)
onreadystatechange事件 ,IE5~10下readyState變化就會觸發該事件。
readyState屬性 ,用于表示LINK元素目前的資源裝載狀态,預設值為"uninitialized",資源加載中為"loading",資源加載完成為"complete"(注意:資源加載完成不代表資源被成功加載)
本次實驗将建立 LINK元素 并對其的 href屬性 分别賦予以下内容 test.css 、 fsjohnhuang.png 、 :0 、 空字元串 、 空白字元串 、 //:0 、 javascript:void 0 和 data:image/png,foo 。并訂閱img元素的onload和onerror事件,IE5~10下還訂閱了onreadystatechange事件,統計整理其在IE5~11、Chrome和FF下的行為特點和事件響應延時。具體實驗統計如下:
測試環境:
1. 測試頁面位址為http://localhost:9000/test.html
2. 圖檔fsjohnhuang.png的大小為12KB
3. test.css的大小為0KB
4. LINK元素已加入渲染樹,rel屬性值為stylesheet,disabled屬性為false(注意:FF下disabled為true,依然會觸發事件)
LINK元素加載資源的前提是加入到渲染樹,rel屬性值有效(Chrome下則還需要disabled為false)。
5. 通過DOM 0方式訂閱事件
符号說明:
N/A 表示該列事件不觸發
href屬性值
備注
Chrome
FireFox
IE5~11
onload事件
onerror事件
IE11
IE5~10
on
ready
state
change
test.css
有效URI,
URI自動補全為
http://localhost
:9000/test.css
首次延時為5ms
N/A
後續讀取緩存為0~1ms
後續讀取緩存為0~1ms
首次onload延時9ms,後續讀取緩存則為0~1ms
1. 首次加載時,先觸
發兩次onreadystate
change事件,從"uninitialized"->"loading"->
"complete"。然後
觸發onload事件。
2. 後續則從緩存中加載
資源,先觸發一次onreadystatechange
事件,從"unitialized"->"complete"。然後觸
發onload事件。
fsjohnhuang.png
:9000/fsjohnhu
ang.png
首次延時為4ms
後續讀取緩存為0~2ms
延時為3~7ms
不會緩存資源
延時為7~33ms
IE9~10中
觸發兩次onreadystatechange
事件(延時0~2ms, 10~12ms),
"unintialized"->
"loading"->
"complete",
。然後
觸發onload事件
(延時為6~22ms) 不會對資源進行緩存
IE5~8中
1.首次加載會發起請求,
會觸發兩次onreadystatechange
事件,"uninitialized"-
>"loading"->
在觸發onload事件,緩存資源;
2.後續加載會從緩存
讀取資源,觸發一次onreadystatechange
事件,"uninitialized"
->"complete"。然後
在觸發onload事件。
:0
無效URI,
URI自動補全為http://localhost
:9000/:0
延遲為6~300ms
發起網絡請求,傳回404 HTTP狀态碼
N/A
延遲為13~30ms
延遲為10ms左右
觸發兩次onreadystatechange
"complete",然後在
觸發onload事件(延時11~13ms)
發起網絡請求,傳回404 HTTP狀态碼
空字元串,""
無效URI
不發起請求
不發起請求
延時為0~1ms
IE9~10中
1.首次加載,僅會觸發onreadystatechange
事件,且僅從
"unitialized"->
"loading";
2.後續加載,
先觸發兩次onreadystatechange
事件,且從
"unitialized"->"complete",
然後再觸發onload事件
1.首次加載,僅會觸發
onreadystatechange
先觸發一次onreadystatechang
e事件,且從
然後再觸發onload事
不發起網絡請求
空白字元串," "
不會對資源進行緩存
延時為5~22ms
觸發一次onreadystatechange
事件,
"uninitialized"-
"complete"。
然後在觸發onload事件。不會緩存資源
//:0
無效URI,會自動補全為http://:0/
延時為1~4ms
事件(延時0~2ms, 5~8ms),readyState
均為"complete",
然後在觸發onload事件
(延時5~9ms)
事件(延時3ms),readyState為
然後在觸發
(延時5~8ms)
不會緩存資源
javascript:void 0
無效的JavaScript URI Scheme
延時為0~8ms
發起網絡請求,但浏覽器會取消該請求
延時為0~3ms
IE8~10中
會觸發一次onreadystatechage
事件(2~4ms),
"uninitialized"
->"loading"
IE5~7中
每次加載均會在設定
`link.href=
"javascript:void 0";`
時會報“無法設定href
屬性。已中止操作”的
異常,但後面依然會
觸發一次onreadystatechage
"uninitialized"->"loading"
資源一直處于加載未完成的狀态
data:image/png,f
無效的Data URI Scheme
延時為0~7ms
不會觸發網絡請求
延時為0~2ms
觸發兩次onreadystatechange事件(延時1~2ms, 5~8ms),readyState均為"complete",然後在觸發onload事件(延時5~9ms)
觸發一次onreadystatechange事件(延時3ms),readyState為"complete",然後在觸發onload事件(延時5~8ms)
從表格資料得到以下規律:
1. onerror絕對不會被觸發;
2. IE5~8中的onload事件均在readyState為"complete"且onreadystatechange事件觸發後才觸發,對于IE11中沒有readyState屬性和onreadystatechange事件,則參考IE5~8中的readyState,若能轉換為"complete"則會觸發onload事件。
3. 對于有效樣式資源(如test.css),首次加載readyState值從"uninitialized"->"loading"->"complete",然後緩存資源;後續對加載同一資源時則從緩存讀取,readyState值從"uninitialized"->"complete"。
4. 對于與資源MIME類型與type屬性值不符的資源(如fsjohnhuang.png,空白字元串),IE9~11均不會對資源進行緩存,且readyState值從"uninitialized"->"loading"->"complete";而IE5~8則會對資源進行緩存,readyState值從"uninitialized"->"complete"。
5. 對于無效路徑的HTTP URI Scheme資源(如:0),IE5~11均不會對資源進行緩存,readyState值從"uninitialized"->"loading"->"complete";
6. 對于空字元串,IE行為十分詭異,IE9~10中首次加載readyState值從"uninitialized"->"loading",後續加載則觸發兩次onreadystatechange事件,且readyState值從"unintialized"->"complete"->"complete"。IE5~8中首次加載readyState值從"uninitialized"->"loading",後續加載則觸發一次onreadystatechange事件,readyState值從"unintialized"->"complete"。
7. 對于//:0,IE會取消網絡請求,IE9~10中會觸發兩次onreadystatechange事件,且readyState值從"unintialized"->"complete"->"complete"。IE5~8中觸發一次onreadystatechange事件,且readyState值從"unintialized"->"complete"。
8. 對于JavaScript URI Scheme資源(如javascript:void 0),IE行為較為統一,均觸發一次onreadystatechange事件,且readyState值從"unintialized"->"loading"。而IE5~7會在執行a.href='javascript:void 0'時報"無法設定href屬性。已中止操作”的異常。
9. 對于Data URI Scheme資源(如data:image/png,f),IE行為較為統一,均會觸發onreadystatechange事件,且readyState值從"unintialized"->"complete"。差別在于IE9~10觸發兩次事件,IE5~8觸發一次。
1. 對于有效路徑資源(如test.css,fsjohnhuang.png),均加載并緩存起來,然後觸發onload事件;
2. 對于空字元串、空白字元串和//:0,均不作為;
3. 對于無效路徑的HTTP URI Scheme資源(如:0),觸發onerror事件;
4. 對于JavaScript URI Scheme資源(如javascript:void 0),浏覽器會取消其網絡請求,觸發onerror事件;
5. 對于Data URI Scheme資源(如data:image/png,f),不管資源是否有效均觸發onload事件。
1. 對于有效路徑資源且資源類型與type屬性值比對的(如test.css),将加載并緩存起來,然後觸發onload事件;
2. 對于無效路徑資源或資源類型與type屬性值不比對的(如fsjohnhuang.png,:0,//:0,空白字元串),則觸發onerror事件;
3. 對于空字元串,則不作為;
5. 對于Data URI Scheme資源(如data:image/png,f),資源有效則觸發onload事件,無效則觸發onerror事件。
若有纰漏請各位指正,謝謝!
http://www.w3help.org/zh-cn/causes/BX9021
http://www.w3school.com.cn/tags/tag_link.asp
如果您覺得本文的内容有趣就掃一下吧!捐贈互勉!
<a href="http://home.cnblogs.com/u/fsjohnhuang/">^_^肥仔John</a>
<a href="http://home.cnblogs.com/u/fsjohnhuang/followees">關注 - 85</a>
<a href="http://home.cnblogs.com/u/fsjohnhuang/followers">粉絲 - 707</a>
<a>+加關注</a>
2
<a></a>
評論清單
太牛了,我還是第一次考慮link這個标簽的事情呢
http://pic.cnblogs.com/face/395638/20140818132358.png
<a href="http://www.ucancode.com/index.htm" target="_blank">【推薦】超50萬VC++源碼: 大型工控、組态\仿真、模組化CAD源碼2018!</a>
<a href="https://cloud.tencent.com/developer/support-plan?fromSource=gwzcw.710852.710852.710852" target="_blank">【推薦】加入騰訊雲自媒體扶持計劃,免費領取域名&伺服器</a>
<b>最新IT新聞</b>:
<b>最新知識庫文章</b>:
<a href="https://github.com/fsjohnhuang" target="_blank">肥仔John@github</a>
作品:
<a href="https://github.com/fsjohnhuang/iScheme" target="_blank">iScheme—Scheme解釋器</a>