欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

javascript 特性檢測并非瀏覽器檢測

 更新時(shí)間:2010年01月15日 16:41:59   作者:  
NCZ在他的同名博客《Feature detection is not browser detection》中,講述了一直以來前端開發(fā)中的一個(gè)熱門技術(shù)——檢測用戶的瀏覽器平臺(tái),并詳細(xì)地?cái)⒄f歷史發(fā)展以及各種辦法的優(yōu)缺點(diǎn)。
我大致翻譯了部分文章,可能有理解錯(cuò)誤的地方,敬請指正。值得一提的是,評論部分的爭論亦值得一看。

特性檢測
起初前端工程師們就極力反對瀏覽器檢測,他們認(rèn)為類似user-agent嗅探的方法是很不好的,理由是它并不是一種面向未來的代碼,無法適應(yīng)新版的瀏覽器。更好的做法是使用特性檢測,就像這樣:
復(fù)制代碼 代碼如下:

if (navigator.userAgent.indexOf("MSIE 7") > -1){
//do something
}

而更好的做法是這樣:
復(fù)制代碼 代碼如下:

if(document.all){
//do something
}

這兩種方式并不相同。前者是檢測瀏覽器的特殊名稱和版本;后者卻是檢測瀏覽器的特性。UA嗅探能夠精確得到瀏覽器的類型和版本(至少能得知瀏覽器類型),而特性檢測卻是去確定瀏覽器是否擁有某個(gè)對象或者支持某個(gè)方法。注意這兩者是完全不同的。
因?yàn)樘匦詸z測依賴于哪些瀏覽器支持,當(dāng)出現(xiàn)新版本瀏覽器的時(shí)候需要繁瑣的確認(rèn)工作。例如DOM標(biāo)準(zhǔn)剛出現(xiàn)的時(shí)候,并不是所有瀏覽器都支持getElementById()方法,所以一開始代碼可能是這樣:
復(fù)制代碼 代碼如下:

if(document.getElementById){ //DOM
element = document.getElementById(id);
} else if (document.all) { //IE
element = document.all[id];
} else if (document.layers){ //Netscape < 6
element = document.layers[id];
}

這是特性檢測很好的一個(gè)例子,亮點(diǎn)在于當(dāng)其它瀏覽器開始支持getElementById()方法時(shí)不必修改代碼。
混合方式
后來前端工程師們考慮改進(jìn)的寫法,代碼變化成這樣:
復(fù)制代碼 代碼如下:

//AVOID!!!
if (document.all) { //IE
id = document.uniqueID;
} else {
id = Math.random();
}

這個(gè)代碼的問題是通過檢測document.all屬性來確定是否是IE。當(dāng)確定是IE后,假定使用私有的document.uniqueID屬性也是安全的。然而,目前所作的只是確定是否支持document.all,并非是去辨識瀏覽器是否為IE。僅僅支持document.all的話也不意味著document.uniqueID是可用的。
后來人們開始這樣寫,用下面那行代替上面的:
var isIE = navigator.userAgent.indexOf("MSIE") > -1;
//下面這行代替上面那行
var isIE = !!document.all;這些變化說明大家對“不要使用UA嗅探”存在誤解——不再對瀏覽器的詳細(xì)信息進(jìn)行檢測,取而代之的是通過特性的支持來推斷。這種基于瀏覽器特性檢測的方式非常不好。
后來前端們發(fā)現(xiàn)document.all并不可靠,更好的檢測IE變?yōu)椋?
var isIE = !!document.all && document.uniqueID;這種實(shí)現(xiàn)方式陷入歧途。不僅需要費(fèi)時(shí)費(fèi)事地去識別瀏覽器所增加的特性支持,另外也不能確定其它瀏覽器開始支持相同的特性。
如果你認(rèn)為這樣的代碼并未被廣泛使用,那么看看來自于老版本的Mootools代碼片段吧:
復(fù)制代碼 代碼如下:

//from MooTools 1.1.2
if (window.ActiveXObject) window.ie = window[window.XMLHttpRequest ? 'ie7' : 'ie6'] = true;
else if (document.childNodes && !document.all && !navigator.taintEnabled) window.webkit = window[window.xpath ? 'webkit420' : 'webkit419'] = true;
else if (document.getBoxObjectFor != null || window.mozInnerScreenX != null) window.gecko = true;

注意它是如何使用特性檢測的。我可以指出它一系列的問題,比如通過檢測window.ie會(huì)將ie8誤認(rèn)為ie7。
余波
隨著瀏覽器的快速發(fā)展,使用特性檢測變得越來越困難和不可靠。但是Mootools 1.2.4仍然使用這一方法,例如:getBoxObjectFor()。
復(fù)制代碼 代碼如下:

//from MooTools 1.2.4
var Browser = $merge({
    Engine: {name: 'unknown', version: 0},
    Platform: {name: (window.orientation != undefined) ? 'ipod' : (navigator.platform.match(/mac|win|linux/i) || ['other'])[0].toLowerCase()},
    Features: {xpath: !!(document.evaluate), air: !!(window.runtime), query: !!(document.querySelector)},
    Plugins: {},
    Engines: {
        presto: function(){
            return (!window.opera) ? false : ((arguments.callee.caller) ? 960 : ((document.getElementsByClassName) ? 950 : 925));
        },
        trident: function(){
            return (!window.ActiveXObject) ? false : ((window.XMLHttpRequest) ? ((document.querySelectorAll) ? 6 : 5) : 4);
        },
        webkit: function(){
            return (navigator.taintEnabled) ? false : ((Browser.Features.xpath) ? ((Browser.Features.query) ? 525 : 420) : 419);
        },
        gecko: function(){
            return (!document.getBoxObjectFor && window.mozInnerScreenX == null) ? false : ((document.getElementsByClassName) ? 19 : 18);
        }
    }
}, Browser || {});

應(yīng)該怎么做?
特性檢測是個(gè)應(yīng)該避免的方法,盡管直接進(jìn)行特性檢測是個(gè)很好的方法,并且大部分情況下能滿足需求。一般只要在檢測前知道這個(gè)特性是否被實(shí)現(xiàn)即可,而不會(huì)去考慮它們之間的關(guān)系。
我并非是說永遠(yuǎn)不使用瀏覽器特性檢測而是基于UA嗅探,因?yàn)槲蚁嘈潘€是有很多用途的,然而我不相信它有很多合理的用途。如果你考慮UA嗅探的話,請先貫徹這一思想:唯一安全的方式是針對特定瀏覽器的特定版本,超出范圍之外都是不可靠的——例如新出的瀏覽器版本。其實(shí)這樣做也是個(gè)明智的辦法,因?yàn)橄噍^于向前兼容不確定的新版本而言,向后兼容老版本是最簡單的做法。

相關(guān)文章

  • JS函數(shù)修改html的元素內(nèi)容,及修改屬性內(nèi)容的方法

    JS函數(shù)修改html的元素內(nèi)容,及修改屬性內(nèi)容的方法

    下面小編就為大家?guī)硪黄狫S函數(shù)修改html的元素內(nèi)容,及修改屬性內(nèi)容的方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-10-10
  • 一文熟練掌握J(rèn)avaScript的switch用法

    一文熟練掌握J(rèn)avaScript的switch用法

    在JavaScript中switch語句是一種用于多條件分支的控制語句,下面這篇文章主要給大家介紹了關(guān)于如果通過一文熟練掌握J(rèn)avaScript的switch用法的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-01-01
  • 使用threejs實(shí)現(xiàn)滾動(dòng)效果的示例代碼

    使用threejs實(shí)現(xiàn)滾動(dòng)效果的示例代碼

    某一天我在刷抖音時(shí),看到一個(gè)UI設(shè)計(jì)師分享了一個(gè)好看的網(wǎng)頁滾動(dòng)動(dòng)效設(shè)計(jì),那種飄逸流暢的動(dòng)畫效果立刻抓住了我的眼球,我腦海里立刻開始想象用代碼如何實(shí)現(xiàn)這個(gè)效果,所以本文給大家分享了如何使用threejs實(shí)現(xiàn)滾動(dòng)效果,感興趣的朋友可以參考下
    2024-01-01
  • JS實(shí)現(xiàn)對json對象排序并刪除id相同項(xiàng)功能示例

    JS實(shí)現(xiàn)對json對象排序并刪除id相同項(xiàng)功能示例

    這篇文章主要介紹了JS實(shí)現(xiàn)對json對象排序并刪除id相同項(xiàng)功能,涉及javascript針對json格式數(shù)據(jù)的遍歷、運(yùn)算、判斷、添加、刪除等相關(guān)操作技巧,需要的朋友可以參考下
    2018-04-04
  • js實(shí)現(xiàn)仿Discuz文本框彈出層效果

    js實(shí)現(xiàn)仿Discuz文本框彈出層效果

    這篇文章主要介紹了js實(shí)現(xiàn)仿Discuz文本框彈出層效果的方法,可實(shí)現(xiàn)點(diǎn)擊文本框彈出窗口選擇數(shù)據(jù)的效果,涉及鼠標(biāo)事件及頁面自定義彈出窗口的相關(guān)操作技巧,需要的朋友可以參考下
    2015-08-08
  • SVG描邊動(dòng)畫

    SVG描邊動(dòng)畫

    本文主要介紹了SVG描邊動(dòng)畫的相關(guān)實(shí)例,具有很好的參考價(jià)值,下面跟著小編一起來看下吧
    2017-02-02
  • 自定義的一個(gè)簡單時(shí)尚js下拉選擇框

    自定義的一個(gè)簡單時(shí)尚js下拉選擇框

    下拉選擇框,是我們在網(wǎng)頁中經(jīng)常使用到的,在本文為大家詳細(xì)介紹下使用js使用的下拉選擇框
    2013-11-11
  • javascript生成json數(shù)據(jù)簡單示例分享

    javascript生成json數(shù)據(jù)簡單示例分享

    這篇文章主要介紹了javascript生成json數(shù)據(jù)示例,需要的朋友可以參考下
    2014-02-02
  • JavaScript中函數(shù)柯里化示例詳解

    JavaScript中函數(shù)柯里化示例詳解

    JavaScript 函數(shù)柯里化是將一個(gè)多參數(shù)的函數(shù)轉(zhuǎn)換為一系列單參數(shù)的函數(shù),每個(gè)單參數(shù)函數(shù)都可以接收一個(gè)參數(shù),并返回一個(gè)新的函數(shù),本文將通過代碼示例給大家講講JavaScript函數(shù)柯里化的優(yōu)缺點(diǎn),需要的朋友可以參考下
    2023-09-09
  • JavaScript實(shí)現(xiàn)的微信二維碼圖片生成器的示例

    JavaScript實(shí)現(xiàn)的微信二維碼圖片生成器的示例

    二維碼分享功能大多是由后端實(shí)現(xiàn)的,對服務(wù)器的負(fù)載較重,這里有一個(gè)前端實(shí)現(xiàn)的版本,本文介紹了JavaScript實(shí)現(xiàn)的微信二維碼圖片生成器的示例,有需要的可以了解一下。
    2016-10-10

最新評論