“變則通,通則達”,在coding的時候也要做到,有時候思路往往太過于局限性,拿今天寫自己的js框架(暫定名為YQ吧,以后文章通用)對瀏覽器判斷方法的實例,來說說代碼思路的轉變。
關于javascript對瀏覽器的判斷,很早之前我寫過一篇文章《js判斷瀏覽器的函數,可區分chrome,safari》。YQ框架中也是采用的這個方法,可是后來想到了有位網友說判斷火狐的版本號會錯誤,這是因為火狐的version的判斷走了正則,而沒有考慮到firefox的,其實不止firefox有這個bug。首先來看看火狐的navigator.userAgent:
這個是我的firefox(3.6.15,卻顯示3.6.8,不知何解,查看關于也是這個問題:版本不統一)
Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8 QQDownload/1.7
根據正則的寫法,火狐的版本號應該這樣寫/Firefox[/]([w.]+)/
而safari的確是類似的:
……Version/3.1 Safari/525.13
其中Version為實際的版本號,也是我們常稱呼的版本號。
開始寫js判斷瀏覽器的,跟jQuery的$.browser一樣,可是版本號會出現問題,只不過是加了個chrome判斷而已。開始想解決方法,初步想得是通過一個正則對象把瀏覽器的名稱和版本號統一匹配出來,正則對象設置如下:
var browserRegExp = { ie:/(msie)[ ]([w.]+)/, firefox:/(firefox)[ |/]([w.]+)/, chrome:/(chrome)[ |/]([w.]+)/, safari:/version[ |/]([w.]+)[ ](safari)/, opera:/(opera)[ |/]([w.]+)/ }
這個對象的設計還是有一定技巧的(后面提到),因為我后面要使用一個遍歷,把全部的正則匹配一遍,生成一個類似$.browser的對象。但是仔細想想,我們在使用判斷的時候怎么使用呢?無非是下面的使用:
$.browser.msie&&$.browser.version==='6.0'
上面的使用方法,可是轉變為下面的使用方法:
$.browser==='msie'&&$.browserVersion==='6.0'
$.browser為瀏覽器的名稱,$.browserVersion為版本號,這樣就不用使用的時候每次都走正則判斷,提高了效率。
根據上面的分析,我們需要先判斷出來瀏覽器名稱和版本號,然后分別給$.browser、$.browserVersion賦值,于是有了下的YQ代碼:
for(var i in browserRegExp){ var match = browserRegExp[i].exec(ua); if(match){ YQ.browser = match[1]; YQ.browserVersion = match[2]; break; } }
前面提到了小技巧,就是把用戶群體大瀏覽器放在前面,減少循環次數,IE在國內肯定是第一啦,其次FF,chrome……依次下來。
細心的童鞋應該看到了safari判斷出來YQ.browser和YQ.browserVersion是相反的,要解決這個問題,就來了第三次轉變!語文不好,不知道咋說這次轉變了,直接上代碼:
var ua = navigator.userAgent.toLowerCase(), browserRegExp = { ie:/msie[ ]([w.]+)/, firefox:/firefox[ |/]([w.]+)/, chrome:/chrome[ |/]([w.]+)/, safari:/version[ |/]([w.]+)[ ]safari/, opera:/opera[ |/]([w.]+)/ };YQ.browser = 'unknow';YQ.browserVersion = '0';for(var i in browserRegExp){ var match = browserRegExp[i].exec(ua); if(match){ YQ.browser = i; YQ.browserVersion = match[1]; break; }}alert(YQ.browser);alert(YQ.browserVersion);
這樣,我們獲得的YQ.browser 就是對象的key,如果IE則YQ.browser 為ie,而不是msie,實際上更加方便記憶了,而且不用多余的判斷來處理safari版本號和名稱倒置的問題了。
仔細觀察多想多看會有不少發現的,我有代碼潔癖,能少寫判斷就少寫,能少用循環就少用!呵呵。
繼續coding YQ……(狀態:愛墻寫完了,YQ正在檢查ing)