關鍵要點
- JavaScript 的特性檢測(測試程序員想要使用的特性)並不總是可靠的。例如,在 Internet Explorer 中測試 ActiveXObject 以進行 Ajax 請求、映射到 DOM 屬性的 HTML 屬性以及對用戶行為的假設(例如檢測觸摸設備)等。
- 當特性檢測失敗時,有時需要採用瀏覽器檢測。但是,建議使用專有對象測試而不是 navigator 信息,並將其用於排除瀏覽器而不是包含瀏覽器。
- 在實現瀏覽器檢測時,務必極其小心。始終首先假設完全符合特性測試,只有在知道某個特性無法按預期工作時才求助於瀏覽器檢測。此外,用於對象和特性測試的語法會影響檢測的成功率,因此選擇正確的語法至關重要。
曾經,瀏覽器檢測是 JavaScript 程序員的看家本領。如果我們知道某些功能在 IE5 中有效但在 Netscape 4 中無效,我們會測試該瀏覽器並相應地修改代碼。例如:
if (navigator.userAgent.indexOf('MSIE 5') != -1) { // 我们认为此浏览器是 IE5 }
但是,當我第一次加入這個行業時,軍備競賽就已經開始了!供應商正在向用戶代理字符串添加額外的值,因此它們看起來像是其競爭對手的瀏覽器,也是它們自己的瀏覽器。例如,這是 Mac 版 Safari 5:
<code>Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/534.59.10 (KHTML, like Gecko) Version/5.1.9 Safari/534.59.10</code>
這將匹配對“Safari”、“Webkit”以及“KHTML”(Webkit 基於的Konqueror 代碼庫)的測試;但它也匹配“Gecko”(這是Firefox 的渲染引擎),當然還有“Mozilla ”(由於歷史原因,幾乎每個瀏覽器都聲稱自己是Mozilla)。
添加所有這些值的目的是規避瀏覽器檢測。如果腳本假設只有 Firefox 才能處理特定功能,否則可能會排除 Safari,即使它可能也能工作。別忘了用戶自己可以更改他們的用戶代理——我曾經將我的瀏覽器設置為識別為“Googlebot/1.0”,這樣我就可以訪問網站所有者認為僅供抓取的內容!
因此,隨著時間的推移,這種瀏覽器檢測已成為一個不可能解開的亂麻,並且在很大程度上已不再使用,取而代之的是更好的東西——特性檢測。
特性檢測只是測試我們想要使用的特性。例如,如果我們需要getBoundingClientRect
(獲取元素相對於視口的位置),那麼重要的是瀏覽器是否支持它,而不是它是哪個瀏覽器;因此,與其測試受支持的瀏覽器,不如測試特性本身:
if (typeof document.documentElement.getBoundingClientRect != "undefined") { // 浏览器支持此函数 }
不支持該函數的瀏覽器將返回“undefined”類型,因此不會通過條件。無需在任何特定瀏覽器中測試腳本,我們就知道它要么正確工作,要么靜默失敗。
或者我們……?
但事實是——特性檢測也不是完全可靠的——有時它會失敗。因此,讓我們現在看看一些示例,看看我們可以做些什麼來解決每個案例。
ActiveX 對象
也許特性檢測失敗最著名的例子是測試 ActiveXObject 以在 Internet Explorer 中進行 Ajax 請求。
ActiveX 是後期綁定對象的示例,其實際意義是您無法知道它是否受支持直到您嘗試使用它。因此,如果用戶禁用了 ActiveX,則以下代碼將引發錯誤:
if (navigator.userAgent.indexOf('MSIE 5') != -1) { // 我们认为此浏览器是 IE5 }
要解決此問題,我們需要使用異常處理——嘗試實例化對象,捕獲任何失敗,並相應地處理它:
<code>Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/534.59.10 (KHTML, like Gecko) Version/5.1.9 Safari/534.59.10</code>
映射到 DOM 屬性的 HTML 屬性
屬性映射通常用於測試與 HTML5 屬性一起使用的 API 的支持。例如,通過查找可拖動屬性來檢查具有 [draggable="true"]
的元素是否支持拖放 API:
if (typeof document.documentElement.getBoundingClientRect != "undefined") { // 浏览器支持此函数 }
這裡的問題是 IE8 或更早版本會自動將所有HTML 屬性映射到 DOM 屬性。這就是為什麼 getAttribute
在這些舊版本中如此混亂的原因,因為它根本不返回屬性,而是返回 DOM 屬性。
這意味著如果我們使用已經具有屬性的元素:
if (typeof window.ActiveXObject != "undefined") { var request = new ActiveXObject("Microsoft.XMLHTTP"); }
那麼即使它們不支持,IE8 或更早版本也會返回 true
用於 ("draggable" in element)
。
屬性可以是任何內容:
if (typeof window.ActiveXObject != "undefined") { try { var request = new ActiveXObject("Microsoft.XMLHTTP"); } catch (ex) { request = null; } if (request !== null) { //... 我们有一个请求对象 } }
但結果將相同——IE8 或更早版本將返回 true
用於 ("nonsense" in element)
。
在這種情況下,解決方案是使用不具有該屬性的元素進行測試,最安全的方法是使用創建的元素:
if ("draggable" in element) { // 浏览器支持拖放 }
對用戶行為的假設
您可能已經看到使用以下代碼來檢測觸摸設備:
<div draggable="true"> ... </div>
大多數觸摸設備在觸發點擊事件之前會實現人工延遲(通常約為 300 毫秒),這是為了避免在雙擊元素的同時也點擊它們。但這會使應用程序感覺遲緩且無響應,因此開發人員有時會使用該特性測試來分叉事件:
<div nonsense="true"> ... </div>
但是,此條件源於一個錯誤的假設——因為設備支持觸摸,因此將使用觸摸。但是觸摸屏筆記本電腦呢?用戶可能正在觸摸屏幕,也可能正在使用鼠標或觸控板;上面的代碼無法處理這種情況,因此用鼠標單擊將不會執行任何操作。
在這種情況下,解決方案根本不是測試事件支持——而是同時綁定兩個事件,然後使用 preventDefault
來阻止觸摸生成點擊:
if (navigator.userAgent.indexOf('MSIE 5') != -1) { // 我们认为此浏览器是 IE5 }
完全不起作用的東西
承認這一點很痛苦,但有時我們不需要測試的不是特性——而是瀏覽器——因為特定瀏覽器聲稱支持某些不起作用的東西。最近的一個例子是 Opera 12 中的 setDragImage()
(這是拖放 dataTransfer
對象的一種方法)。
特性測試在這裡失敗是因為 Opera 12 聲稱支持它;異常處理也無濟於事,因為它不會引發任何錯誤。它只是不起作用:
<code>Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/534.59.10 (KHTML, like Gecko) Version/5.1.9 Safari/534.59.10</code>
現在,如果您只想嘗試添加自定義拖動圖像,並且樂於在不支持的情況下保留默認值(這將發生),那麼這可能很好。但是,如果您的應用程序確實需要自定義圖像,以至於不支持它的瀏覽器應該使用完全不同的實現(即使用自定義 JavaScript 來實現所有拖動行為)呢?
或者,如果瀏覽器實現了某些功能,但存在無法避免的渲染錯誤呢?有時我們別無選擇,只能明確檢測有問題的瀏覽器,並將其排除在使用它本來會嘗試支持的功能之外。
因此,問題變成了——實現瀏覽器檢測最安全的方法是什麼?
我有兩點建議:
- 優先使用專有對象測試而不是 navigator 信息。
- 將其用於排除瀏覽器而不是包含瀏覽器。
例如,可以使用 window.opera
對象檢測 Opera 12 或更早版本,因此我們可以使用該排除來測試可拖動支持:
if (typeof document.documentElement.getBoundingClientRect != "undefined") { // 浏览器支持此函数 }
最好使用專有對象而不是標準對象,因為當發布新瀏覽器時,測試結果不太可能發生變化。以下是一些我最喜歡的示例:
if (typeof window.ActiveXObject != "undefined") { var request = new ActiveXObject("Microsoft.XMLHTTP"); }
對象測試也可以與特性測試結合使用,以確定特定瀏覽器中特定特性的支持,或者在緊急情況下,定義更精確的瀏覽器條件:
if (typeof window.ActiveXObject != "undefined") { try { var request = new ActiveXObject("Microsoft.XMLHTTP"); } catch (ex) { request = null; } if (request !== null) { //... 我们有一个请求对象 } }
我們已經註意到用戶代理字符串是一個不可靠的混亂,但供應商字符串實際上相當可預測,並且可以用來可靠地測試 Chrome 或 Safari:
if ("draggable" in element) { // 浏览器支持拖放 }
所有這一切的黃金法則是要極其小心。確保您在盡可能多的瀏覽器中測試條件,並仔細考慮它們的向前兼容性——目標是使用瀏覽器條件來排除瀏覽器,因為存在已知的錯誤,而不是因為已知的特性而包含它們(這就是特性測試的目的)
從根本上說,始終首先假設完全符合特性測試——除非您知道情況並非如此,否則假設特性將按預期工作。
選擇測試語法
在結束之前,我想檢查一下我們可以用於對象和特性測試的不同類型的語法。例如,近年來,以下語法已變得很常見:
if (navigator.userAgent.indexOf('MSIE 5') != -1) { // 我们认为此浏览器是 IE5 }
過去我們無法使用它,因為 IE5 及其同類產品會因語法而引發錯誤;但現在我們不必支持這些瀏覽器,這已不再是問題。
從本質上講,它與以下內容完全相同,但編寫起來更短:
<code>Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/534.59.10 (KHTML, like Gecko) Version/5.1.9 Safari/534.59.10</code>
但是,測試條件通常依賴於自動類型轉換:
if (typeof document.documentElement.getBoundingClientRect != "undefined") { // 浏览器支持此函数 }
我們在某些瀏覽器對象測試(例如window.opera
測試)中早些時候使用了該語法,這是安全的,因為對像如何評估——任何已定義的對像或函數都將始終評估為true,而如果它未定義,則將評估為false。
但是我們可能正在測試有效返回 null 或空字符串的東西,這兩者都評估為 false。例如,style.maxWidth
屬性有時用於排除 IE6:
if (typeof window.ActiveXObject != "undefined") { var request = new ActiveXObject("Microsoft.XMLHTTP"); }
只有在支持 maxWidth
屬性並且具有作者定義的值時,它才會評估為 true,因此如果我們這樣編寫測試,它可能會失敗:
if (typeof window.ActiveXObject != "undefined") { try { var request = new ActiveXObject("Microsoft.XMLHTTP"); } catch (ex) { request = null; } if (request !== null) { //... 我们有一个请求对象 } }
一般規則是這樣的:依賴於自動類型轉換對於對象和函數是安全的,但對於字符串和數字或可能為 null 的值並不一定安全。
話雖如此——如果您能安全地使用它,那就這樣做,因為它在現代瀏覽器中通常要快得多(可能是因為它們針對這種類型的條件進行了優化)。
有關此內容的更多信息,請參閱:現實世界中的自動類型轉換。
關於 JavaScript 特性檢測的常見問題
什麼是 JavaScript 特性檢測,為什麼它很重要?
JavaScript 特性檢測是開發人員用來確定用戶瀏覽器是否支持特定特性或 API 的一種技術。這至關重要,因為並非所有瀏覽器都支持 JavaScript 的所有特性。通過使用特性檢測,開發人員可以為不受支持的特性提供替代解決方案或後備方案,確保網站或應用程序在不同瀏覽器上都能正確運行。這增強了用戶體驗並確保了兼容性。
JavaScript 特性檢測是如何失敗的?
JavaScript 特性檢測可能會由於多種原因而失敗。一個常見的原因是特性檢測代碼的實現不正確。例如,如果代碼檢查對像中不存在的屬性,它將返回 undefined,導致假陰性。另一個原因可能是瀏覽器的怪癖或錯誤,這可能會導致特性檢測給出不准確的結果。
特性檢測和瀏覽器檢測有什麼區別?
特性檢測涉及檢查用戶瀏覽器是否支持特定特性或 API,而瀏覽器檢測則識別用戶的瀏覽器和版本。雖然這兩種技術都旨在確保兼容性和功能性,但特性檢測通常被認為是一種更好的實踐,因為它直接檢查特性,而不是根據瀏覽器類型或版本來假設其支持。
如何使用 JavaScript 檢測移動設備?
您可以使用 JavaScript 中的 navigator.userAgent
屬性來檢測移動設備。此屬性返回一個字符串,表示瀏覽器的用戶代理標頭。通過檢查此字符串中的特定關鍵字(例如“Android”、“iPhone”或“iPad”),您可以確定用戶是否在移動設備上。
什麼是 Feature.js,它如何幫助進行特性檢測?
Feature.js 是一個輕量級、快速且簡單的 JavaScript 實用程序,用於特性檢測。它提供易於使用的 API,允許開發人員測試瀏覽器是否支持特定特性。這有助於為不受支持的特性提供後備方案或替代解決方案,從而增強網站或應用程序的兼容性和功能性。
什麼是 Modernizr,它如何幫助進行特性檢測?
Modernizr 是一個 JavaScript 庫,可幫助開發人員利用 HTML5 和 CSS3 特性,同時保持與舊版瀏覽器的兼容性。它使用特性檢測來檢查瀏覽器是否支持特定特性,並將類添加到 HTML 元素,允許您在樣式表或 JavaScript 中定位特定瀏覽器功能。
如何使用 device-detector-js 包進行特性檢測?
device-detector-js 包是用於設備檢測的強大工具。它解析用戶代理字符串並檢測智能手機、平板電腦、台式機、電視機等設備。它還檢測瀏覽器、引擎、操作系統和其他有用信息。您可以使用此包根據檢測到的設備調整網站或應用程序的行為。
實施特性檢測的一些最佳實踐是什麼?
實施特性檢測的一些最佳實踐包括:使用可靠且經過測試的庫(如Modernizr 或Feature.js)、在不同的瀏覽器和設備上徹底測試您的特性檢測代碼、為不受支持的特性提供替代解決方案或後備方案以及避免根據瀏覽器類型或版本來假設特性支持。
特性檢測能否幫助提高網站性能?
是的,特性檢測可以幫助提高網站性能。通過檢測不受支持的特性並提供替代解決方案或後備方案,您可以防止不必要的代碼在瀏覽器中運行。這可以減少加載時間並提高網站的整體性能。
如何了解不同瀏覽器支持的最新特性?
由於 Web 開發的快速發展,了解不同瀏覽器支持的最新特性可能具有挑戰性。但是,Mozilla 開發者網絡 (MDN)、Can I Use 和 JavaScript 文檔等資源可以提供有關不同瀏覽器中特性支持的最新信息。
以上是當JavaScript功能檢測失敗時的詳細內容。更多資訊請關注PHP中文網其他相關文章!

JavaScript字符串替換方法詳解及常見問題解答 本文將探討兩種在JavaScript中替換字符串字符的方法:在JavaScript代碼內部替換和在網頁HTML內部替換。 在JavaScript代碼內部替換字符串 最直接的方法是使用replace()方法: str = str.replace("find","replace"); 該方法僅替換第一個匹配項。要替換所有匹配項,需使用正則表達式並添加全局標誌g: str = str.replace(/fi

利用輕鬆的網頁佈局:8 ESTISSEL插件jQuery大大簡化了網頁佈局。 本文重點介紹了簡化該過程的八個功能強大的JQuery插件,對於手動網站創建特別有用

因此,在這裡,您準備好了解所有稱為Ajax的東西。但是,到底是什麼? AJAX一詞是指用於創建動態,交互式Web內容的一系列寬鬆的技術。 Ajax一詞,最初由Jesse J創造

本教程演示了創建通過Ajax加載的動態頁面框,從而可以即時刷新,而無需全頁重新加載。 它利用jQuery和JavaScript。將其視為自定義的Facebook式內容框加載程序。 關鍵概念:Ajax和JQuery

10款趣味橫生的jQuery遊戲插件,讓您的網站更具吸引力,提升用戶粘性!雖然Flash仍然是開發休閒網頁遊戲的最佳軟件,但jQuery也能創造出令人驚喜的效果,雖然無法與純動作Flash遊戲媲美,但在某些情況下,您也能在瀏覽器中獲得意想不到的樂趣。 jQuery井字棋遊戲 遊戲編程的“Hello world”,現在有了jQuery版本。 源碼 jQuery瘋狂填詞遊戲 這是一個填空遊戲,由於不知道單詞的上下文,可能會產生一些古怪的結果。 源碼 jQuery掃雷遊戲

此JavaScript庫利用窗口。名稱屬性可以管理會話數據,而無需依賴cookie。 它為瀏覽器中存儲和檢索會話變量提供了強大的解決方案。 庫提供了三種核心方法:會話

本教程演示瞭如何使用jQuery創建迷人的視差背景效果。 我們將構建一個帶有分層圖像的標題橫幅,從而創造出令人驚嘆的視覺深度。 更新的插件可與JQuery 1.6.4及更高版本一起使用。 下載


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能

Safe Exam Browser
Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Linux新版
SublimeText3 Linux最新版

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),