Javascript 浏览器检测与特征检测

Javascript 浏览器检测与特征检测,javascript,html,dom,cross-browser,Javascript,Html,Dom,Cross Browser,我要扮演一个魔鬼代言人。我一直在想,为什么浏览器检测(相对于特征检测)被认为是一种彻头彻尾的糟糕做法。如果我测试了某个浏览器的某个版本,并确认某个功能的行为是以某种可预测的方式进行的,那么决定对其进行特殊处理似乎是可以的。理由是它在未来将是万无一失的,因为这种部分浏览器版本不会改变。另一方面,如果我检测到DOM元素具有函数X,则不一定意味着: 此函数在所有浏览器中的工作方式相同,并且 更重要的是,即使在未来的所有浏览器中,它也将以同样的方式工作 我刚刚浏览了jQuery源代码,他们通过在DOM中

我要扮演一个魔鬼代言人。我一直在想,为什么浏览器检测(相对于特征检测)被认为是一种彻头彻尾的糟糕做法。如果我测试了某个浏览器的某个版本,并确认某个功能的行为是以某种可预测的方式进行的,那么决定对其进行特殊处理似乎是可以的。理由是它在未来将是万无一失的,因为这种部分浏览器版本不会改变。另一方面,如果我检测到DOM元素具有函数X,则不一定意味着:

  • 此函数在所有浏览器中的工作方式相同,并且
  • 更重要的是,即使在未来的所有浏览器中,它也将以同样的方式工作
  • 我刚刚浏览了jQuery源代码,他们通过在DOM中插入一段精心构建的HTML片段来进行功能检测,然后检查它是否具有某些功能。这是一种明智且可靠的方法,但我想说,如果我在我的一小段个人JavaScript(没有jQuery)中做了这样的事情,那就有点太重了。它们还具有几乎无限的QA资源的优势。另一方面,你经常看到人们做的是检查函数X是否存在,然后基于此,他们假设函数在所有具有此函数的浏览器中都会以某种方式运行


    我并不是说特征检测不是一件好事(如果使用正确的话),但我想知道为什么浏览器检测通常会立即被忽略,即使它听起来合乎逻辑。我想知道这是否是另一种流行的说法。

    理想的解决方案是将功能和浏览器检测结合起来。前者因为您提到的几点而失败,而后者因为浏览器有时发布错误信息以“使事情正常运行”

    Mozilla有一个很好的解决方案,可能对您也有帮助

    从 “在其历史的不同时期,Web的使用一直由一个浏览器主导,以至于许多网站设计为仅使用该特定浏览器,而不是根据W3C和IETF等机构的标准。此类网站通常包括“浏览器嗅探”“代码,它根据收到的用户代理字符串更改发送的信息。这可能意味着不太受欢迎的浏览器不会发送复杂的内容,即使它们可能能够正确处理这些内容,或者在极端情况下拒绝所有内容。因此,各种浏览器“伪装”或“欺骗”这个字符串,以便将自己识别为此类检测代码的其他对象;通常,浏览器的真实身份随后会包含在字符串中。”

    解释了功能检测在许多方面如何优于浏览器嗅探

    事实上,嗅探是非常脆弱的。理论上它是脆弱的,因为它依赖于一个任意的
    用户代理
    字符串,然后实际上将该字符串映射到某个行为。正如时间所证明的,它在实践中也是脆弱的。测试几十个浏览器的每个主要和次要版本,并尝试解析构建其中一些版本的数量根本不切实际;另一方面,测试某些行为是否有怪癖要可靠得多。例如,功能测试常常捕捉到浏览器供应商之间偶然复制的错误和不一致

    根据我自己在IE8中修复Prototype.js的经验,我知道如果我们一开始不嗅探的话,90%的问题是可以避免的


    在修复Prototype.js时,我发现一些需要测试的功能实际上在js库中非常常见,因此我为任何愿意摆脱嗅探的人收集了一些功能。

    在我看来,自从几年前Resig以来,浏览器检测一直受到广泛的反对。然而,Resig的评论是错误的特定于库/框架代码,即其他[特定于域的]应用程序/站点将使用的代码

    我认为功能检测毫无疑问非常适合于库/框架。但对于特定领域的应用程序,我不确定浏览器检测是否有那么差。它适合于处理难以进行功能检测的已知浏览器特征,或者适用于在其功能实现中存在缺陷的浏览器lf.浏览器检测适当的次数:

    • 不是跨浏览器的站点/应用程序,需要显示针对该客户端浏览器的警告/对话框/不同页面裁剪。这在旧版应用程序中很常见
    • 银行或私人网站对支持的浏览器和版本有严格的政策(以避免可能危害用户数据的已知安全漏洞)
    • 微优化:有时候,当以某种方式执行某些操作时,一个浏览器的速度比其他浏览器快得离谱。根据您的用户群,在特定的浏览器/版本上进行分支可能是有利的
    • IE6缺乏png透明度
    • 许多显示/渲染问题(请阅读:IE css支持)仅在特定浏览器版本中出现,您实际上不知道要测试哪些功能
    这就是说,在进行浏览器检测时,有一些(可能是我们中的大多数人)需要避免。

    “在我看来,自从几年前重新发布这篇文章以来,浏览器检测一直受到广泛的反对“。早在那篇文章发表之前,浏览器检测就是一种糟糕的做法。我不认为你使用浏览器检测堆栈的任何理由。在哪个内部网应用程序中缺少对PNG透明度的支持是一个阻碍?编写跨浏览器网站现在比以往任何时候都要简单,只要对新功能采用务实的方法,例如,你真的会因为浏览器不支持const或let而放弃对浏览器的支持吗?@RobG:我从来没有说过“浏览器检测”等于“拒绝访问”或“放弃支持”