天天看點

JS魔法堂:LINK元素深入詳解

一、前言                            

  我們一般使用方式為 <link type="text/css" rel="stylesheet" href="text.css"> 來引入外部層疊式樣式檔案,但LINK元素各屬性的具體含義、資源加載行為等方面卻了解不多,本文打算稍微深入一下。

  由于内容較多,特設目錄一坨:

  也許我們常常會看到一下兩種寫法

JS魔法堂:LINK元素深入詳解
JS魔法堂: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。

JS魔法堂:LINK元素深入詳解
JS魔法堂:LINK元素深入詳解

     僅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. 定義網站收藏夾圖示

JS魔法堂:LINK元素深入詳解
JS魔法堂:LINK元素深入詳解

     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方式建立。下面代碼為簡單的實作方式:

JS魔法堂:LINK元素深入詳解
JS魔法堂:LINK元素深入詳解

  資源加載首先當然是确定資源位置的 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

如果您覺得本文的内容有趣就掃一下吧!捐贈互勉!

JS魔法堂:LINK元素深入詳解
JS魔法堂:LINK元素深入詳解
JS魔法堂:LINK元素深入詳解

<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">【推薦】加入騰訊雲自媒體扶持計劃,免費領取域名&amp;伺服器</a>

JS魔法堂:LINK元素深入詳解

<b>最新IT新聞</b>:

JS魔法堂:LINK元素深入詳解

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

繼續閱讀