如何使用JavaScript检测Internet Explorer 6的最佳方法?

17

使用JavaScript检测Internet Explorer 6的最佳方法是什么?

If browser == IE6 {
    alert('hi');
}

45
如果(一切都崩溃了),那么IE6=true。 - womp
7
@woot4moo:嗯,既然是IE6,那也没关系了。 - TIMEX
2
@womp,这段代码在IE6上无法工作;在IE6上什么都不能用... - Rubens Farias
9个回答

33

条件注释是一个不错的替代方案:

<!--[if IE 6]>
<script>
var everythingIsBroken = true;
</script>
<![endif]-->

编辑:如果你仍然在2017年或之后寻求支持IE6......好吧,我很同情你。在2017年回答这个问题的答案是真的不用担心IE6了。它不再是一个得到支持的浏览器。任何能够运行该浏览器的操作系统和浏览器本身都不再获得安全更新。这意味着使用此软件的用户面临极大的被攻击风险。这对于那些无法承担升级费用的人来说是一个大问题。


7
应该这样。条件注释是微软引入的一种方法,只在(特定版本的)IE中运行某些代码。由于它们位于HTML注释中,其他浏览器将会忽略它。 - Aistina
6
还有哪些浏览器是这样的?如果你要支持使用Trident4的第三方浏览器,那么你将面临比仅仅条件注释不起作用更多的问题……你最好支持W3.org的Amaya。忽略安德鲁的评论,条件注释始终对“低级”浏览器有效。 - Bjorn
3
条件注释是微软针对IE6的推荐定位方式。 - Bjorn
3
Internet Explorer 6使用Trident 4引擎,但我想这已经不是重点了... - Andrew Moore
2
仅因原问题包含“使用Javascript”一词而被踩。HTML条件注释不是Javascript解决方案。当您编写可移植的Javascript,例如Javascript库时,您需要一个Javascript解决方案。 - thomasrutter
显示剩余4条评论

29

冒着真正回答问题的风险(并假设问者有一个好的理由来特别检测IE6):

if (/\bMSIE 6/.test(navigator.userAgent) && !window.opera) {
  // yep, browser claims to be IE6
}

10
谢谢你实际回答了问题,没有发表关于为什么应该使用特性检测的长篇大论。在某些情况下,浏览器检测仍然是完全有效的。 - Lightweight
3
如果你想要进行特性检测,那么在大多数情况下(当人们询问有关浏览器检测问题时)特性检测是更好的选择。然而,当你需要为某个特定浏览器版本中的 bug 应用解决方法时,特性检测通常无法实现(例如,可能是呈现方面的 bug,因此它无法被“检测”)。如果你使用基于用户代理的浏览器检测,你需要确保正则表达式仅针对特定的有问题版本,而不是未来的版本 - 否则,当未来版本的浏览器“修复”该 bug 时,你的代码将会出现问题。 - thomasrutter
我搜索这个信息的原因是为了在HTC文件中检测IE6,它已经被默认识别为Internet Explorer,但是IE6和IE8、9、10、11、12需要不同的解决方案来修复CSS。你对问题的回答也回答了我的问题。我希望生活在一个IE浏览器遵循标准的世界里,但事实并非如此,给那些用户提供有缺陷的页面并不代表我所服务的品牌。无论好坏(大多数情况下是坏的),我都必须处理IE。 - Wayne
等等,难道ie6不支持正则表达式吗?这可能无法通过。 - user7847084
JavaScript 中的 RegExp 支持至少可以追溯到 Netscape 4 和 IE5。 - thomasrutter
显示剩余2条评论

7
  var ua = window.navigator.userAgent;
  var msie = ua.indexOf ( "MSIE " );

  if ( msie > 0 )      // If Internet Explorer, return version number
     return parseInt (ua.substring (msie+5, ua.indexOf (".", msie )));
  else                 // If another browser, return 0
     return 0;

Source : http://support.microsoft.com/kb/167820


1
-1:永远不要使用用户代理来识别浏览器。改用基于特性的检测方法。 - Andrew Moore
为什么?它在IE、FF和Chrome上都能正常工作! - Hannoun Yassir
@Yassir:有很多浏览器使用与MSIE 6相同的引擎(Trident 4)。使用特性检测而不是用户代理检测可以捕获这些浏览器。它还比用户代理检测具有更少的误报(许多浏览器都有更改其UA以通过另一个浏览器的选项)。 - Andrew Moore
11
为什么你要给这个回答点踩?是的,特性检测是可以的,但他在适当地回答了提问者的问题。很确定提问者没有要求关于特性检测比浏览器检测更好的分析解释。 - Will Morgan
1
终于有一个回答实际问题的答案了。然而,它不是很简洁。正则表达式会更好。 - thomasrutter
2
@Andrew,没有人问如何检测使用Trident但不是IE6的浏览器。问题特别涉及IE6。 - kibibu

5
不要基于用户代理来进行检测。还有许多其他使用Trident 4引擎(IE6使用的引擎)但并非IE6的浏览器。
答案很简单:不要检测浏览器,而应检测引擎。为此,您必须使用所谓的特性检测。
使用基于特征的检测具有以下优点:
  • 检测所有使用与目标相似渲染引擎的浏览器。
  • 更容易的代码分支来解决渲染引擎问题。
  • 较少的误报(UA可以被修改以通过另一个浏览器,但无法修改特征)。
下面的脚本使用浏览器特性来检测引擎。感谢 MooTools 生产团队(http://mootools.net/developers/)。 注意:下面的片段已经被修改为不需要 MooTools javascript 框架即可工作。如果您确实希望使用 MooTools,则不再需要此代码,它是分发的一部分。
function $tryCatch(){
    for (var i = 0, l = arguments.length; i < l; i++){
        try {
            return arguments[i]();
        } catch(e){}
    }
    return null;
};

var Browser = {

    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.Platform[Browser.Platform.name] = true;

Browser.detect = function(){

    for (var engine in this.Engines){
        var version = this.Engines[engine]();
        if (version){
            this.Engine = {name: engine, version: version};
            this.Engine[engine] = this.Engine[engine + version] = true;
            break;
        }
    }

    return {name: engine, version: version};

};

Browser.detect();

Browser.Request = function(){
    return $tryCatch(function(){
        return new XMLHttpRequest();
    }, function(){
        return new ActiveXObject('MSXML2.XMLHTTP');
    }, function(){
        return new ActiveXObject('Microsoft.XMLHTTP');
    });
};

Browser.Features.xhr = !!(Browser.Request());

Browser.Plugins.Flash = (function(){
    var version = ($tryCatch(function(){
        return navigator.plugins['Shockwave Flash'].description;
    }, function(){
        return new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version');
    }) || '0 r0').match(/\d+/g);
    return {version: parseInt(version[0] || 0 + '.' + version[1], 10) || 0, build: parseInt(version[2], 10) || 0};
})();

function $exec(text){
    if (!text) return text;
    if (window.execScript){
        window.execScript(text);
    } else {
        var script = document.createElement('script');
        script.setAttribute('type', 'text/javascript');
        script[(Browser.Engine.webkit && Browser.Engine.version < 420) ? 'innerText' : 'text'] = text;
        document.head.appendChild(script);
        document.head.removeChild(script);
    }
    return text;
};

只需包含这个JavaScript类,您就可以通过以下方式检测IE6和使用Trident4引擎的任何其他浏览器:

if(Browser.Engine.trident4) {
   alert('IE6 or similar...');
} elseif(Browser.Engine.name == "trident") {
   alert('Internet Explorer Trident Rendering Engine Version ' + Browser.Engine.version);
}

2
这似乎不是你在评论中建议其他答案时推荐的特性检测方法。 - Tim Down
@Tim Down:我说的是基于特征的检测,而不是特征检测。 基于特征的检测试图根据特定渲染引擎的JavaScript引擎中实现的特征来识别引擎。 特征检测允许您根据是否检测到支持来打开或关闭功能。 知道用于呈现页面的引擎可以帮助您修复该页面上动态元素呈现的怪癖。 这种方法也称为基于对象的检测。 - Andrew Moore
4
这是特性推断,且不稳定。基于document.getBoxObjectForwindow.mozInnerScreenXnavigator.taintEnabled的存在,你可能会做出什么样的推断?如果你将使用它们来改变与这些被测试对象无关的行为,那么这只是比检查userAgent字符串略微高级一点而已。这些对象可以被JavaScript覆盖,并且通常是非标准的,因此受浏览器制造商的影响:MooTools最近就因此受到了打击(http://ajaxian.com/archives/mootools-call-to-upgrade)。 - Tim Down
4
不想把这个回答单独挑出来,但总的来说,我很厌烦在Stackoverflow上看到那些基本上只说“不要那样做”的问题回答。我们不能相信问题提问者有一个特别检测IE6的好理由吗?而不是进行基于特性的检测?例如,可能问题提问者想要实现一个警告给用户,说“您的Internet Explorer版本已经过时”。 - thomasrutter

4

最可靠的方法是使用条件注释,如@apphacker所提到的。然而,似乎不太为人知的是,条件注释也可以用于JavaScript:

var div = document.createElement("div");
div.innerHTML = "<!--[if IE 6]><i></i><![endif]-->";
var isIe6 = (div.getElementsByTagName("i").length == 1);

alert("Is IE 6: " + isIe6);

1

非常晚的补充。

除了apphacker的答案中使用的HTML条件注释外,微软的JScript实现还提供了JavaScript的条件注释

<script type="text/javascript">
    var isIE6 = /*@cc_on/*@if(@_jscript_version<=5.6)1@else@*/0/*@end@*/;

    if (isIE6) {
        alert("You're screwed");
    }
</script>

好处是它也可以用于外部JavaScript文件(.js)。

有关Microsoft主机应用程序实现的JScript版本列表,请参见:JavaScript版本信息


那并不是技术上的条件注释:它被称为条件编译,是一种独立的机制。而且,它也无法准确地用于检测正在运行的IE版本,因为JScript可以独立于浏览器升级。 - Tim Down

1

什么是使用JavaScript检测<browser_x>的最佳方法?

不用。

正如安德鲁·摩尔在本帖的评论中提到的,您应该使用功能检测。这将使您的代码更具“未来性”。如果另一个浏览器在未来包含或不再支持某个功能,则您的代码将是安全的。有许多网站解释如何处理此问题。概念是巨大的,涵盖了很多概念,因此,而不是在此写一篇文章/书籍,以下是一些可用的资源:


假设在特定的浏览器版本中存在渲染错误,您想要解决此问题,但仅针对该浏览器和版本进行操作(例如,假设透明背景在按钮上呈现错误)。在这种情况下,不存在功能检测 - 您无法“功能检测”渲染错误。在现实世界中,并非每个浏览器中的怪癖都可以进行功能检测,而且您不能仅仅认为询问浏览器检测的人不如您聪明或没有充分的理由这样做。 - thomasrutter
@thomasrutter 并非所有的渲染错误都无法进行特性检测。但是,通常来说,渲染错误是CSS问题,有其自己的一套策略,与特定于浏览器的JavaScript分开。这个问题特别询问了JavaScript,如果编写正确,几乎不需要浏览器检测。提问者没有具体说明想要进行浏览器检测的原因,在这里已经提到了足够多的IE6检测策略。我提供了一种替代方案,提问者可能不知道,对90%的情况会更好。 - Dan Herbert
很感动你回复了一篇你两年前发表的帖子上的新评论 :) - thomasrutter

0
<!--[if (IE 6)|(IE 7)]>
<script>
    alert("Lesser browser detected!");
</script>
<![endif]-->

0

我不确定你是否有特殊原因想要检测IE 6,但通常最好尝试检测浏览器的功能而不是检测浏览器本身。您可以使用jQuery.support轻松实现此操作,具体请参考http://api.jquery.com/jQuery.support/


2
推荐某人在解决一个简单问题时使用庞大的JavaScript库或框架,真的是个好主意吗?明明不需要这样的东西来解决问题。 - Bjorn
我不会把jQuery称为“庞大的”。发帖者所询问的内容实际上是不应该做的,因此更有价值的建议是解释为什么不应该这样做,以及他/她应该做什么,以便遵循良好的编程实践。 - jhchen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接