css3出來已經好久了,如今來談判斷瀏覽器是否支持某個css3的屬性雖然說有點過期了,可是仍是能夠談談的,而後,此篇主要談的不是判斷是否支持,而是怎麼封裝更好,爲何這麼封裝,歡迎吐槽。javascript
入題,判斷瀏覽器是否支持css3 transition,方法很簡單,只須要下面這句代碼就好了:css
'transition' in document.body.style
chrome和ie支持document.body,可是Firefox不支持,Firefox支持document.documentElement,對於沒有doctype聲明的ie又不支持document.documentElement。html
因此用建立一個都支持的元素,而後經過判斷屬性在元素的style裏是否存在便可:java
'transition' in document.createElement( 'i' ).style
固然這是標準下,對於老點的chrome或者Firefox,它們不支持transition,可是支持帶前綴的transition,好比chrome 裏css寫成-webkit-transition: 1s;因而js也須要對這種狀況進行斷定,向後兼容。css3
如今貼一段簡潔的封裝代碼,而後再逐步解析,以免繁雜,產生不了全局觀:git
function cssProperty( attr ){ var prefix = [ 'O', 'ms', 'Moz', 'Webkit' ], length = prefix.length, style = document.createElement( 'i' ).style; cssProperty = function( attr ){ if( attr in style ){ return true; } attr = attr.replace( /^[a-z]/, function( val ){ return val.toUpperCase(); }); var len = length; while( len-- ){ if( prefix[ len ] + attr in style ){ return true; } } return false; }; return cssProperty( attr ); }
接下來是一段一段的解釋。github
爲何直接聲明prefix = [ 'O', 'ms', 'Moz', 'Webkit' ]
而不使用字符串切割prefix = 'O ms Moz Webkit'.split( ' ' ),其餘人不少都是這樣寫的。
經筆者測試,測試代碼以下,爲了避免必要的影響,我兩段代碼一塊兒測試和兩段代碼分別測試都作了觀察,結果無差。web
爲了偷懶,估計其餘瀏覽器應該也是差很少的結果就不作ie的測試了:chrome
測試結果以下,單位ms:數組
很明顯,直接聲明prefix = [ 'O', 'ms', 'Moz', 'Webkit' ]的代碼執行效率更高。
再看[ 'O', 'ms', 'Moz', 'Webkit' ]是25個字節,'O ms Moz Webkit'.split( ' ' )是28個字節,即使是從文件大小方面,前者也優賽過後者。
然而爲何不少國外包括jQuery源碼裏都是用split分割的形式呢?
(ps:jQuery-2.1.3源碼5738行寫cssPrefix時,是用的直接賦值,代碼如右:cssPrefixes = [ "Webkit", "O", "Moz", "ms" ])
緣由我猜大概是這樣的:對於分割的字符串種類比較多時,採用split有利於文件字節的減小,而執行效率縮小99999倍後幾乎能夠忽略不計,可是對於文件被下載更快,雖然說也能夠忽略不計,可是選擇這邊比選擇執行效率那邊要好一點吧。
(ps:或許還有個緣由就是書寫split的這條代碼方便吧,不像數組那樣,一會單引號,一會逗號方括號的...。若是是爲了裝逼就算了)
迴歸正題,迴歸到咱們這裏,兩邊咱們都賽過,因此,毋庸置疑的就應該選擇前者。
● 對於網上有些不緩存而每次去獲取style的代碼,我想說,難道同個瀏覽器環境下,下一秒這個元素的style就變了嗎,難道不一樣元素它是style也是變的,難道div元素支持transition,其餘某個元素就不支持transition了?!還有就是不利於壓縮,不利於文件尺寸的減少,提升下載速度。
下面這個代碼來自國外的誰(固然中國好像不少都是直接不假思索的就拷貝過來了):http://code.tutsplus.com/tutorials/quick-tip-detect-css3-support-in-browsers-with-javascript--net-16444
● 仔細一看,會發現爲何個人排列是這樣的:O ms Moz Webkit,而別人的是這樣的:Webkit Moz O ms;
理由來自2015年瀏覽器市場份額排行榜:http://tools.yesky.com/420/93749420.shtml
在國內,Opera PC版估計沒什麼用,並且它早已轉向webkit內核了,ie就不談了,對於開發者來講坑太多了,看不到好效果就看不到吧,對不起了。
因此,整體來講,排名依次是chrome,Firefox,ie,opera。
在後面的while循環判斷代碼中,是倒序判斷的,因此從執行效率的角度講,
大部分狀況是chrome訪問,因此就第一個判斷webkit內核,知足條件就跳出循環,減小執行,提升運行效率。
● 個人代碼裏多了 var len = length; 用下面的代碼測試一下,環境是(老版一點的)瀏覽器都只支持帶前綴的這兩個屬性(好比Firefox13),測試國外代碼第二個及之後的alert彈出的都會是false,由於它耗盡了len。
alert( cssProperty( 'columns' ) ) alert( cssProperty( 'animation' ) )
● 函數封裝以下封裝,若是像國外那種柯里化封裝表示js一加載完就會執行外層的匿名函數,而後把新函數賦值給supports,若是頁面必定會用到檢測函數,那麼這種方法與下面的封裝效果無差,可是若是頁面不必定用到,即cssProperty變成了整站全局函數,或許另多個頁面用到,因而像下面這樣封裝就不會形成函數的自執行,只有第一次調用函數的時候,函數纔會執行,而後被賦予新值,詳情能夠參考一下《JavaScript高級程序設計第三版》惰性載入函數。
function cssProperty( attr ){ //...code
cssProperty = function( attr ){ //...code
}; return cssProperty( attr ); }
最後歡迎訪問個人Github,歡迎Star,歡迎Fork,一塊兒成長。