文章出處

一、前言                            

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

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

  二、到底有沒有結束標簽?

  三、普通屬性介紹

  四、屬性disabled詳解

    1. Attribute和Property的disabled

  2. disabled為true還會加載樣式文件嗎?

    3. disabled為true還會觸發onload、onerror和onreadystatechange事件嗎?

    4. CSS解析

  5. 渲染

  五、屬性rel介紹

  六、動態創建LINK元素

  七、與資源加載相關的屬性和事件

  八、資源加載實驗

  1. IE下的結論

  2. Chrome下的結論

  3. FF下的結論

  九、總結

  十、參考

 

二、到底有沒有結束標簽?                    

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

<!-- 無結束標簽 -->
<link type="text/css" rel="stylesheet" href="test.css">
<!-- 閉合標簽 -->
<link type="text/css" rel="stylesheet" href="test.css"/>

  參考官網可知:

在 HTML 中,<link> 標簽沒有結束標簽。

在 XHTML 中,<link> 標簽必須被正確地關閉。

三、普通屬性介紹                          

  1.  屬性media ,指定該樣式應用到的顯示設備(媒介類型),默認值為all,還有值screen(顯示器)和print(打印機)被瀏覽器支持。另外還有一堆為成為事實標準的值。

  2.  HTML5屬性sizes ,用于指定網頁圖標高寬(格式: 高x寬 或默認值 any ),需要同時配置 rel="icons" ,示例:

<link type="images/png" href="fsjohnhuang.png" rel="icons" sizes="16x16"/>

  3.  屬性type ,引入的資源MIME類型,注意:不規定必須為text/css

四、屬性disabled詳解                       

  下列內容主要參考《HTML中Link元素disable屬性詳解》的內容,并補充一些實踐過程中踩過的坑。

  1. Attribute和Property的disabled(若想了解更多屬性、特性的信息可參考《JS魔法堂:屬性、特性,傻傻分不清楚》

    由于disabled屬于標準屬性,因此可以通過點方式(property)和getAttribute方式(Attribute)對其進行操作。對于IE和Chrome,兩者是同步的。但對于FF來說兩者是分離的。

   1. 對于靜態引入LINK元素,且通過Attribute方式設置disabled為true,由于Attribute和Property是分離的,此時FF下通過點方式操作的disabled依然為false(而IE、Chrome的則為true),而是否應用到元素渲染上則由點方式操作的disabled的值來決定,因此該方式在FF下依然會應用到元素渲染上,而在IE和Chrome上則不會應用到元素渲染上。

<link type="text/css" rel="stylesheet" href="text.css" disabled="true"/>

   2. FF中需要靜態或動態引入LINK元素時,都必須等LINK元素被添加到渲染樹中后才可以通過點方式修改disabled,否則修改無效,disabled值一直為false。

// FF下
var link = document.createElement('link');
link.rel = 'stylesheet';
link.href = 'test.css';
console.log(link.disabled); // false
link.disabled = true;
console.log(link.disabled); // false
// 加入DOM樹,還未加入渲染樹
document.body.appendChild(link);
link.disabled = true;
setTimeout(function(
    console.log(link.disabled); // false  
    link.disabled = true;
    console.log(link.disabled); // true
), 0);

  2. disabled為true還會加載樣式文件嗎?

     僅Chrome在disabled為true時,不加載樣式文件。其他瀏覽器均依然繼續加載文件資源。

  3. disabled為true還會觸發onload、onerror和onreadystatechange事件嗎?

  由于FF下通過Attribute方式設置disabled為true,和在LINK元素未加入渲染樹前修改disabled為true均無效,因此僅FF下會觸發onload和onerror事件。其他瀏覽器均不會觸發onload、onerror和onreadystatechange事件。

     由于FF下存在上述特性,因此可以通過如下手段設置FF下的樣式的disabled為true。

<link id="test" type="text/css" rel="stylesheet" href="test.css" onload="this.disabled=true;"/>

  4. CSS解析

     首先需要理解的是CSS解析到底是什么?

   其實就是在成功加載樣式文件后,將樣式文件中的樣式添加到樣式表document.styleSheets中。而應用到元素渲染的樣式則為document.styleSheets的子集。

     由于對于disabled為true的LINK元素,Chrome將不加載其樣式文件,因此也無法將文件中的樣式添加到document.styleSheets中;也只有Chrome在將disabled屬性從false動態修改為true時,會從document.styleSheets中刪除該樣式文件的樣式。其他瀏覽器只要成功加載樣式文件就會將其中的樣式添加到document.styleSheets中,無論disabled屬性值是什么。

  5. 渲染(頁面元素與CSS屬性結合呈現到頁面上)

     只要LINK元素的點方式的disabled為true,那么它所關聯的樣式規則均不生效。(FF則需要經過上述的特殊處理)

  對于想通過樣式文件書寫樣式規則,但又想通過document.styleSheets按需提取應用樣式的情況,由于Chrome采用直接不加載樣式文件的處理方式,因此需要通過如下手段處理:

<link id="test" type="text/css" rel="stylesheet" href="test.css" onload="this.disabled=true;"/>

 

五、屬性rel介紹                        

  屬性rel用于規定當前文檔與被加載的資源之間的關系。

  1. 定義網站收藏夾圖標

<link rel="shortcut icon" href="http://paranimage.com/wp-content/themes/v5/images/favicon.ico" type="images/x-icon"/>
<link rel="icon" href="http://paranimage.com/wp-content/themes/v5/images/favicon.png" type="images/png"/>

     IE下rel必須為 shortcut icon ,而且圖標必須為 .ico格式  。而其他瀏覽器的rel只需寫為 icon ,圖標不一定需要使用 .ico格式 。

  2. 定義蘋果桌面上的網站圖標

<link rel="apple-touch-icon" href="http://paranimage.com/wp-content/themes/v5/images/apple-touch-icon.png" />

  3. RSS地址和Pingback地址

<link rel="alternate" type="application/rss+xml" title=" RSS Feed" href="rss.html" />
<link rel="alternate" type="application/atom+xml" title="Atom Feed" href="atom.html" />
<link rel="pingback" href="pingback.html" />

 

六 、動態創建LINK元素                    

  動態創建元素一般有兩種方式,分別是document.createElement方法和innerHTML+firstChild。對于LINK元素,在IE9+和其他現代瀏覽器中可使用innerHTML+firstChild方式創建LINK元素,而在IE5~8中則需要使用document.createElement方式創建。下面代碼為簡單的實現方式:

var $ = function(){
   // 提取tagName、attributes整體和innerHTML
  var rTag = /<([a-z]+)\s*([^>]*)(?:\/>|>([^<]*)<\/\1>)/ig,
       // 提取attribute的鍵值
       rAttrs = /\s*([a-z]+)\s*=("|')([^'"]*)\2\s*/ig;
   // IE9+和其他瀏覽器的DOM對象生成工廠
   var factory = document.createElement('div');
   return function(html){
    var el = (factory.innerHTML = html, factory.firstChild);
      if (!el){
        var baseInfo = rTag.exec(html);
         try{
           el = document.createElement(baseInfo[1]);
            var innerHTML = baseInfo[baseInfo.length - 1];
            if (innerHTML !== null && typeof innerHTML !== 'undefined' && innerHTML !== '')
              el.innerHTML = innerHTML;
                var attrStr = baseInfo[2];
                var groups;
                while(groups = rAttrs.exec(attrStr))
                  el.setAttribute(groups[1], groups[3]);
            }
         catch(e){
          return null;
         }
         // 重置正則表達式
         rTag.compile(rTag);
         rAttrs.compile(rAttrs);
      }

      return el;
   };
}();

 

七、與資源加載相關的屬性和事件                  

  資源加載首先當然是確定資源位置的 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事件 備注 onload事件 onerror事件 備注

IE11

onload事件

IE11

onerror事件

IE5~10

on

ready

state

change

備注
test.css

有效URI,

URI自動補全為

http://localhost

:9000/test.css

 首次延時為5ms  N/A  后續讀取緩存為0~1ms  首次延時為5ms  N/A 后續讀取緩存為0~1ms   首次onload延時9ms,后續讀取緩存則為0~1ms  N/A

 1. 首次加載時,先觸

發兩次onreadystate

change事件,從"uninitialized"->"loading"->

"complete"。然后

觸發onload事件。

2. 后續則從緩存中加載

資源,先觸發一次onreadystatechange

事件,從"unitialized"->"complete"。然后觸

發onload事件。

 
fsjohnhuang.png  

有效URI,

URI自動補全為

http://localhost

:9000/fsjohnhu

ang.png

 首次延時為4ms  N/A  后續讀取緩存為0~2ms  N/A  延時為3~7ms  不會緩存資源  延時為7~33ms  N/A

IE9~10中 

觸發兩次onreadystatechange

事件(延時0~2ms, 10~12ms),

"unintialized"->

"loading"->

"complete",

。然后

觸發onload事件

(延時為6~22ms) 不會對資源進行緩存

IE5~8中

1.首次加載會發起請求,

會觸發兩次onreadystatechange

事件,"uninitialized"-

>"loading"->

"complete"。然后

在觸發onload事件,緩存資源;

2.后續加載會從緩存

讀取資源,觸發一次onreadystatechange

事件,"uninitialized"

->"complete"。然后

在觸發onload事件。

 
:0  

無效URI,

URI自動補全為http://localhost

:9000/:0

 N/A  延遲為6~300ms  發起網絡請求,返回404 HTTP狀態碼   N/A  延遲為13~30ms  發起網絡請求,返回404 HTTP狀態碼  延遲為10ms左右  N/A

 觸發兩次onreadystatechange

事件(延時0~2ms, 10~12ms),

"unintialized"->

"loading"->

"complete",然后在

觸發onload事件(延時11~13ms)

  發起網絡請求,返回404 HTTP狀態碼
空字符串,""  無效URI  N/A  N/A  不發起請求  N/A  N/A   不發起請求  延時為0~1ms  N/A

IE9~10中

 1.首次加載,僅會觸發onreadystatechange

事件,且僅從

"unitialized"->

"loading";

2.后續加載,

先觸發兩次onreadystatechange

事件,且從

"unitialized"->"complete",

然后再觸發onload事件

IE5~8中

1.首次加載,僅會觸發

onreadystatechange

事件,且僅從

"unitialized"->

"loading";

2.后續加載,

先觸發一次onreadystatechang

e事件,且從

"unitialized"->"complete",

然后再觸發onload事

 不發起網絡請求
空白字符串,"    "  無效URI  N/A  N/A  不發起請求  N/A  延時為3~7ms  不會對資源進行緩存  延時為5~22ms  N/A

IE9~10中

觸發一次onreadystatechange

事件,

"uninitialized"-

>"loading"->

"complete"。

然后在觸發onload事件。不會緩存資源

IE5~8中

1.首次加載會發起請求,

會觸發兩次onreadystatechange

事件,"uninitialized"-

>"loading"->

"complete"。然后

在觸發onload事件,緩存資源;

2.后續加載會從緩存

讀取資源,觸發一次onreadystatechange

事件,"uninitialized"

->"complete"。然后

在觸發onload事件。

 
//:0  無效URI,會自動補全為http://:0/  N/A   N/A  不發起請求  N/A  延時為1~4ms  不會對資源進行緩存  延時為0~1ms  N/A

IE9~10中

觸發兩次onreadystatechange

事件(延時0~2ms, 5~8ms),readyState

均為"complete",

然后在觸發onload事件

(延時5~9ms)

IE5~8中

觸發一次onreadystatechange

事件(延時3ms),readyState為

"complete",

然后在觸發

onload事件

(延時5~8ms)

不會緩存資源
javascript:void 0  無效的JavaScript URI Scheme  N/A  延時為0~8ms  發起網絡請求,但瀏覽器會取消該請求  N/A  延時為0~3ms  發起網絡請求,但瀏覽器會取消該請求  N/A  N/A

IE8~10中

會觸發一次onreadystatechage

事件(2~4ms),

"uninitialized"

->"loading"

IE5~7中

每次加載均會在設置

`link.href=

"javascript:void 0";`

時會報“無法設置href

屬性。已中止操作”的

異常,但后面依然會

觸發一次onreadystatechage

事件(2~4ms),

"uninitialized"->"loading"

 資源一直處于加載未完成的狀態
data:image/png,f  無效的Data URI Scheme  延時為0~7ms  N/A  不會觸發網絡請求  N/A  延時為0~2ms  不會觸發網絡請求  延時為0~1ms  N/A

IE9~10中

觸發兩次onreadystatechange事件(延時1~2ms, 5~8ms),readyState均為"complete",然后在觸發onload事件(延時5~9ms)

IE5~8中

觸發一次onreadystatechange事件(延時3ms),readyState為"complete",然后在觸發onload事件(延時5~8ms)

 不會觸發網絡請求

    從表格數據得到以下規律:

    IE下

  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觸發一次。

   Chrome下

  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事件。

 FF下

  1. 對于有效路徑資源且資源類型與type屬性值匹配的(如test.css),將加載并緩存起來,然后觸發onload事件;

      2. 對于無效路徑資源或資源類型與type屬性值不匹配的(如fsjohnhuang.png,:0,//:0,空白字符串),則觸發onerror事件;

      3. 對于空字符串,則不作為;

      4. 對于JavaScript URI Scheme資源(如javascript:void 0),瀏覽器會取消其網絡請求,觸發onerror事件;

  5.  對于Data URI Scheme資源(如data:image/png,f),資源有效則觸發onload事件,無效則觸發onerror事件。

 

九、總結                              

  若有紕漏請各位指正,謝謝!

  尊重原創,轉載請注明來自:http://www.cnblogs.com/fsjohnhuang/p/4149793.html  ^_^肥子John

十、參考                              

  http://www.w3help.org/zh-cn/causes/BX9021

  http://www.w3school.com.cn/tags/tag_link.asp


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 AutoPoster 的頭像
    AutoPoster

    互聯網 - 大數據

    AutoPoster 發表在 痞客邦 留言(0) 人氣()