【问题标题】:What is the Best way to do Browser Detection in Javascript?在 Javascript 中进行浏览器检测的最佳方法是什么?
【发布时间】:2010-10-09 23:46:42
【问题描述】:

在我的一个 Web 开发课程中,我们要求创建一个脚本来检测 NE4、NE6+、IE4、IE6+ 浏览器,为每个浏览器显示兼容的 CSS 脚本。

他给了我们一篇关于这些的文章和文章提到的this site

一个学生这样说

javascript 的最佳选择 兼容性是为了测试浏览器 当你想做的时候的能力 某物。主要原因之一 因为这是在未来,更多 并且将创建更多浏览器。

现在我的问题是,哪种方式是检测用户浏览器对象检测或使用导航器对象的最佳方式?

【问题讨论】:

    标签: javascript cross-browser browser-detection


    【解决方案1】:

    最好的方法是尽可能避免使用依赖于浏览器的代码,但在绝对必要的情况下,请使用由比你我了解更多的人编写的已证明正确的代码。我建议使用 JQuery,因为那是我选择的库,但还有很多其他的库(YUI 很流行,Scriptilicious 等也很流行)。谷歌 JQuery 开始。此外,谷歌“John Resig at Google”看看你是否能找到他所做的演讲,他在其中讨论了他用来检测浏览器功能的一些技术。它非常聪明,因为它可以适应浏览器修复它们的遗留问题。

    【讨论】:

      【解决方案2】:

      最好的方法是不检测它,而是使用像 jQuery 这样的跨浏览器兼容库。这在表现力方面还有很多其他优势。

      【讨论】:

      • 太糟糕了,直到最近 jQuery 由于浏览器嗅探而跨浏览器。
      • 你的意思是什么,究竟是什么?我应该只复制 jQuery 的工作方式而不使用它的其余部分吗?使用 jQuery 的好处是你不需要关心你使用的是什么浏览器。已经为你完成了艰苦的工作(你也得到了奖金)。
      【解决方案3】:

      检测所使用的浏览器的标准方法是检查提供的用户代理。

      var BrowserDetect = {
          init: function () {
              this.browser = this.searchString(this.dataBrowser) || "An unknown browser";
              this.version = this.searchVersion(navigator.userAgent)
                  || this.searchVersion(navigator.appVersion)
                  || "an unknown version";
              this.OS = this.searchString(this.dataOS) || "an unknown OS";
          },
          searchString: function (data) {
              for (var i=0;i<data.length;i++) {
                  var dataString = data[i].string;
                  var dataProp = data[i].prop;
                  this.versionSearchString = data[i].versionSearch || data[i].identity;
                  if (dataString) {
                      if (dataString.indexOf(data[i].subString) != -1)
                          return data[i].identity;
                  }
                  else if (dataProp)
                      return data[i].identity;
              }
          },
          searchVersion: function (dataString) {
              var index = dataString.indexOf(this.versionSearchString);
              if (index == -1) return;
              return parseFloat(dataString.substring(index+this.versionSearchString.length+1));
          },
          dataBrowser: [
              {
                  string: navigator.userAgent,
                  subString: "Chrome",
                  identity: "Chrome"
              },
              {   string: navigator.userAgent,
                  subString: "OmniWeb",
                  versionSearch: "OmniWeb/",
                  identity: "OmniWeb"
              },
              {
                  string: navigator.vendor,
                  subString: "Apple",
                  identity: "Safari",
                  versionSearch: "Version"
              },
              {
                  prop: window.opera,
                  identity: "Opera"
              },
              {
                  string: navigator.vendor,
                  subString: "iCab",
                  identity: "iCab"
              },
              {
                  string: navigator.vendor,
                  subString: "KDE",
                  identity: "Konqueror"
              },
              {
                  string: navigator.userAgent,
                  subString: "Firefox",
                  identity: "Firefox"
              },
              {
                  string: navigator.vendor,
                  subString: "Camino",
                  identity: "Camino"
              },
              {       // for newer Netscapes (6+)
                  string: navigator.userAgent,
                  subString: "Netscape",
                  identity: "Netscape"
              },
              {
                  string: navigator.userAgent,
                  subString: "MSIE",
                  identity: "Explorer",
                  versionSearch: "MSIE"
              },
              {
                  string: navigator.userAgent,
                  subString: "Gecko",
                  identity: "Mozilla",
                  versionSearch: "rv"
              },
              {       // for older Netscapes (4-)
                  string: navigator.userAgent,
                  subString: "Mozilla",
                  identity: "Netscape",
                  versionSearch: "Mozilla"
              }
          ],
          dataOS : [
              {
                  string: navigator.platform,
                  subString: "Win",
                  identity: "Windows"
              },
              {
                  string: navigator.platform,
                  subString: "Mac",
                  identity: "Mac"
              },
              {
                     string: navigator.userAgent,
                     subString: "iPhone",
                     identity: "iPhone/iPod"
              },
              {
                  string: navigator.platform,
                  subString: "Linux",
                  identity: "Linux"
              }
          ]
      
      };
      BrowserDetect.init();
      

      http://www.quirksmode.org/js/detect.html

      【讨论】:

      • +1,因为这是最有可能真正帮助他完成任务的一个答案。
      • 基于 UA 的检查通常很差,因为无论浏览器是否修复错误,您最终都会阻止浏览器,不使用新浏览器等。一个很好的例子是 Chrome 必须欺骗由于网站将好的浏览器列入白名单,而不是将坏的浏览器列入黑名单,因此作为许多网站的 Safari。
      • @Olliej:当问题本身是家庭作业时,您将否决一个专门适用于手头问题的答案。我非常怀疑当学生回来说“你不应该那样做”而不是按照他被告知的那样做时,老师会不会高兴。
      • 另外,搜索 WebKit 要比搜索 Safari 好得多,因为这样你就可以获得所有基于 WebKit 的浏览器(Apple 将 WebKit 作为系统框架提供,所以有一些使用它,并且其他一些自定义版本),还有 gtk、qt 和 wx 端口,以及 chrome、android 和 S60 分支。
      • 但是,在某些情况下浏览器检测是必要的 - 例如contenteditable 无法检测到功能的怪癖。
      【解决方案4】:

      在 1.3.2 中弃用的 jQuery.browser() 将返回有用的信息...另请参阅 jQuery.support()

      【讨论】:

        【解决方案5】:

        老实说,如果您尝试检测浏览器,您就是在攻击错误的问题。我的建议是检测您想要使用的功能并在此基础上进行降级。例如,如果您需要创建一个 XMLHttpRequest,类似于以下内容将起作用:

          var xhr = null;
           if (typeof(XMLHttpRequest) !== 'undefined')
              xhr = new XMLHttpRequest(...);
           else if (typeof(ActiveXObject) !== 'undefined')
              xhr = new ActiveXObject('Microsoft.XMLHTTP');
        
           if (xhr != null)
              ...do something with it
           else
              throw "No XMLHttpRequest";
        

        这种方法允许您的应用程序随着浏览器开始支持更多功能而增长。显然,这些类型的检查应该在某个函数中抽象出来,以免一遍又一遍地用相同的检查乱扔代码。

        但是,如果您能够使用 JQuery、Prototype、Dojo、YUI 等 Ajax 库,那可能是您最好的选择,因为它们已经内置了抽象。

        【讨论】:

        • -1,他在他的问题中说这是为了上课,没有理由因为“攻击错误的问题”而跳槽。这是一项任务。
        • @Paolo:我同意。我在这个网站上经常看到这种方式,在这个网站上,回答问题的人会试图引导 OP 走上他们希望他们选择的道路,而不是仅仅按照建议的方式回答问题。
        • 我不同意 - 值得知道你问错了问题。听起来他的讲师没有太多的实际经验,或者没有使用它。 Bryan 的方法是 100% 准确的,除了其他人(阅读 JQuery)已经这样做了:-)。
        • 一个过于笼统的陈述,如“如果你试图检测你正在攻击错误问题的浏览器”可能永远不会是正确的,除非改写得当
        【解决方案6】:

        在我的一个 Web 开发课程中,我们要求创建一个检测 NE4、NE6+、IE4、IE6+ 的脚本

        您的 Web 开发课程已经过时了,可笑又无可救药。

        在 Netscape4 和 IE4 是常见浏览器的时代,通常需要嗅探浏览器类型并为它们提供不同的样式表和脚本,因为它们对样式和 DHTML 功能的支持非常不同。

        如今,您不得不担心的最低质量浏览器的基准浏览器是 IE6。几乎没有人使用比这更低的任何东西,因为 IE6 是随 XP 一起提供的,而使用未升级的 Win2K 和 Win9X 机器的机会微乎其微。当然,世界上没有人在使用 IE4 或糟糕的 Netscape 4。目前很少有网站可以使用它们。

        由于网络标准,您可能想要定位的所有其他浏览器(IE7+、Firefox2+、Opera、Safari、Chrome、Konqueror)通常都足够接近互兼容性,因此您很少需要进行大量浏览器检测。 IE6 确实需要一些注意,但通常如果您使用标准模式,您可以通过一些 CSS hack(特别是“* html”)和脚本中的一些功能嗅探来解决问题,而不必为其提供完全不同的内容。

        现在我的问题是,哪种方式是检测用户浏览器对象检测或使用导航器对象的最佳方式?

        对象/方法检测。

        尽可能避免使用导航器对象;它通常出于兼容性目的而存在,并且扫描字符串以尝试找出浏览器名称很容易在用户代理字符串中遇到意外标记。

        如果您需要专门检测 IE6(这是迄今为止最常见的需要检测和添加解决方法的浏览器),并且没有合适的能力嗅探方式,最好使用 conditional compilation 而不是导航器.userAgent 处理。

        【讨论】:

        • 是的,我知道这门课程有点蹩脚,但这是一个愚蠢的课堂作业,但我能做什么哈哈
        • 在这种情况下,问题不是“在 Javascript 中进行浏览器检测的最佳方法是什么?”如“我必须做些什么愚蠢的事情才能让我的讲师满意?” :-)
        【解决方案7】:

        我构建了一个简单的 Firefox Mac User Agent Detect 来编写特定的 CSS。 http://www.combsconsulting.com/code-firefox-mac-hack.html

        【讨论】:

          【解决方案8】:

          您需要使用 Conditionizr,它为此提供了强大的测试/检测插件:http://conditionizr.com

          例如:

          conditionizr.add('safari', [], function () {
              return /constructor/i.test(window.HTMLElement);
          });
          

          【讨论】:

            猜你喜欢
            • 2011-06-16
            • 2011-12-03
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-03-18
            • 2011-04-26
            • 2012-09-11
            相关资源
            最近更新 更多