1、前言 javascript
咱們通常使用方式爲 <link type="text/css" rel="stylesheet" href="text.css"> 來引入外部層疊式樣式文件,但LINK元素各屬性的具體含義、資源加載行爲等方面卻瞭解很少,本文打算稍微深刻一下。css
因爲內容較多,特設目錄一坨:html
2、到底有沒有結束標籤?java
3、普通屬性介紹web
4、屬性disabled詳解正則表達式
1. Attribute和Property的disabled瀏覽器
3. disabled爲true還會觸發onload、onerror和onreadystatechange事件嗎?網絡
4. CSS解析app
也許咱們經常會看到一下兩種寫法
<!-- 無結束標籤 --> <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。
下列內容主要參考《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);
僅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;"/>
首先須要理解的是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採用直接不加載樣式文件的處理方式,所以須要經過以下手段處理:
<link id="test" type="text/css" rel="stylesheet" href="test.css" onload="this.disabled=true;"/>
屬性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" />
動態建立元素通常有兩種方式,分別是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~十一、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) |
不會觸發網絡請求 |
從表格數據獲得如下規律:
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. 對於空字符串,則不做爲;
4. 對於JavaScript URI Scheme資源(如javascript:void 0),瀏覽器會取消其網絡請求,觸發onerror事件;
5. 對於Data URI Scheme資源(如data:image/png,f),資源有效則觸發onload事件,無效則觸發onerror事件。