在JavaScript中检测IE版本(v9之前)

253

如果用户使用早于v9的Internet Explorer版本,我希望将其反弹到错误页面,因为我们不值得花时间和金钱来支持IE pre-v9。其他非IE浏览器的用户都可以正常使用且无需反弹。这是建议的代码:

if(navigator.appName.indexOf("Internet Explorer")!=-1){     //yeah, he's using IE
    var badBrowser=(
        navigator.appVersion.indexOf("MSIE 9")==-1 &&   //v9 is ok
        navigator.appVersion.indexOf("MSIE 1")==-1  //v10, 11, 12, etc. is fine too
    );

    if(badBrowser){
        // navigate to error page
    }
}

这段代码能实现吗?

在此之前,我想先回应几个可能会出现的评论:

  1. 是的,我知道用户可以伪造他们的 useragent 字符串,但我并不担心。
  2. 是的,我知道编程专家更喜欢检测特性支持而不是浏览器类型,但我认为这种方法在这种情况下并不合理。我已经知道所有(相关的)非 IE 浏览器都支持我需要的功能,而所有的 pre-v9 IE 浏览器都不支持。在整个站点逐个检查每个特性将是一种浪费。
  3. 是的,我知道有人试图使用 IE v1(或 >= 20)来访问网站将不会将 'badBrowser' 设置为 true 并且警告页面将无法正常显示。我们愿意承担这种风险。
  4. 是的,我知道 Microsoft 有 "条件注释" 可以用于精确的浏览器版本检测。但自从 IE 10 起,IE 就不再支持条件注释了,使这种方法变得绝对无用。

还有其他显而易见的问题需要注意吗?


125
“支持IE v9之前的版本不值得我们浪费时间和金钱。” 我很希望我能够做到。 - user377628
2
基于第二点,我不建议使用Modernizr(http://en.wikipedia.org/wiki/Modernizr)-每个人都必须在某个地方划定界限-但是IE9似乎是一个高标准。 - amelvin
1
条件注释只是普通的注释。只有IE将它们解释为特殊注释。IE10+不再这样做了。 - Andreas
3
IE 10将与非IE浏览器一样处理条件注释。它们是有效的HTML注释,将被视为这样的注释。我同意Andreas的看法,并认为条件注释是可行的方法。 - Tim Down
1
谁在乎IE10是否支持条件注释,如果它不是你要检测的浏览器之一?你不需要检测它是否是IE9或更高版本,你只需要检测它是否是IE8或更低版本。你的错误在于认为你需要弄清楚它是什么,才能知道它不是什么。这是不正确的。你不需要检测IE10,你只需要知道它不是IE8(或更低版本)。任何你放在lt IE 9条件中的代码都将在IE8及以下版本中运行,而其他地方则不会。就是这么简单。这是微软在IE方面做对的唯一一件事情。 - Jimbo Jonny
显示剩余5条评论
37个回答

356

这是我首选的方法。它提供最大的控制力。(注意:条件语句仅在IE5-9中受支持。)

首先正确设置您的IE类。

<!DOCTYPE html>
<!--[if lt IE 7]> <html class="lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]>    <html class="lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]>    <html class="lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!--> <html> <!--<![endif]-->    
<head>

那么你可以使用CSS来进行样式例外处理,或者如果需要的话,可以添加一些简单的JavaScript:

(function ($) {
    "use strict";

    // Detecting IE
    var oldIE;
    if ($('html').is('.lt-ie7, .lt-ie8, .lt-ie9')) {
        oldIE = true;
    }

    if (oldIE) {
        // Here's your JS for IE..
    } else {
        // ..And here's the full-fat code for everyone else
    }

}(jQuery));

感谢Paul Irish


22
考虑到原帖请求使用纯 JavaScript 解决方案,我认为下面由@Tim Down提供的答案更好,因为它不涉及更改现有HTML,并且不使用jQuery: https://dev59.com/D2gu5IYBdhLWcg3w8Lev#10965203 - AsGoodAsItGets
我在w3 html验证器上使用此代码时出现错误:错误:在注释中看到<!--。可能的原因:嵌套注释(不允许)。 在第5行,第21列 if gt IE 8]><!--><html - abumalick

162

返回IE版本或如果不是IE则返回false

function isIE () {
  var myNav = navigator.userAgent.toLowerCase();
  return (myNav.indexOf('msie') != -1) ? parseInt(myNav.split('msie')[1]) : false;
}

例子:

if (isIE () == 8) {
 // IE8 code
} else {
 // Other versions IE or not IE
}
或者
if (isIE () && isIE () < 9) {
 // is IE version less than 9
} else {
 // is IE 9 and later or not IE
}
if (isIE()) {
 // is IE
} else {
 // Other browser
}

39
不适用于IE11。从IE 11开始,他们已经将UA字符串更改为“mozilla/5.0 (windows nt 6.3; wow64; trident/7.0; .net4.0e; .net4.0c; media center pc 6.0; .net clr 3.5.30729; .net clr 2.0.50727; .net clr 3.0.30729; rv:11.0) like gecko”。 - Annie
23
请注意,在火狐浏览器中,“false < 9”的结果为“true”。因此,条件应该是 if (isIE () && isIE () < 9) { - nZeus
3
也许它在运行IE7标准模式下?http://msdn.microsoft.com/en-us/library/ie/cc196988(v=vs.85).aspx - mason81
4
批准的答案是如何在HTML中检测IE版本。这回答了原始问题。 - Matt Wagner
2
@PrasadGayan - Microsoft Edge不是Internet Explorer。因此,返回false似乎是它应该做的正确事情。 - BryanGrezeszak
显示剩余3条评论

119

使用条件注释。您正在尝试检测IE < 9的用户,而条件注释将在这些浏览器中起作用;在其他浏览器(IE >= 10和非IE),这些注释将被视为普通的HTML注释,也就是它们的本来面目。

HTML示例:

<!--[if lt IE 9]>
WE DON'T LIKE YOUR BROWSER
<![endif]-->

如果需要,您也可以纯粹使用脚本来完成此操作:

var div = document.createElement("div");
div.innerHTML = "<!--[if lt IE 9]><i></i><![endif]-->";
var isIeLessThan9 = (div.getElementsByTagName("i").length == 1);
if (isIeLessThan9) {
    alert("WE DON'T LIKE YOUR BROWSER");
}

5
@Tim Down的JavaScript版本回答对我非常有用。我使用了BrowserStack,在Windows 7上测试了IE 8、9、10和11;在Mac OS X Snow Leopard上测试了Safari 5.1,Firefox 28.0,Chrome 33.0和Opera 20.0;还测试了iPhone 5上的Mobile Safari和Android Samsung Galaxy Tab 2 10.1 4.0。正如预期的那样,只有IE8报告说它是IeLessThan9。很好! - Steve Saporta

118

如果没有其他人添加了addEventLister方法,并且您正在使用正确的浏览器模式,那么您可以使用以下代码检查IE 8或更低版本:

if (window.attachEvent && !window.addEventListener) {
    // "bad" IE
}

传统的Internet Explorer和attachEvent(MDN)


7
这似乎是在JavaScript中完全检测IE <= 8的最有效方法 - 对于像我这样正在寻找方法的人来说非常棒。 - Gregory Magarshak
太好了!这也可以检测到在怪异模式下的IE9,这正是我一直在寻找的。 - sstur
7
虽然这是一个“易于使用”的解决方案,但它存在一些风险。你公司中的任何人(不知道你的解决方案)都可以使用“addEventListener”或“attachEvent”来处理IE 8中缺少的功能。这样一来,你的代码就无法正常工作了。 - Zé Carlos

60

为了方便检测 MSIE(v6 - v7 - v8 - v9 - v10 - v11):

if (navigator.userAgent.indexOf('MSIE') !== -1 || navigator.appVersion.indexOf('Trident/') > 0) {
   // MSIE
}

适用于检测IE10,因为它不支持条件注释。在IE11中不起作用,但是IE11通常有良好的行为。 - personne3000
11
终于有一个回答不是讲解如何使用特征检测,而是直接回答了问题。 - cdmckay

34

以下是AngularJS 检查 IE 的方法

/**
 * documentMode is an IE-only property
 * http://msdn.microsoft.com/en-us/library/ie/cc196988(v=vs.85).aspx
 */
var msie = document.documentMode;

if (msie < 9) {
    // code for IE < 9
}

哇,这比所有的条件注释都简单多了!没有任何限制吗? - andrewb
根据文档,IE8+支持此属性,因此我认为对于大多数情况来说应该是足够的。 - iurii
根据MSDN的参考文献,“当当前文档尚未确定时,documentMode返回值为零(0)。这通常发生在文档正在加载时。”这是否意味着您可能无法在<head>中加载的脚本中获得有效响应? - Erik Knowles
我认为您可以通过检查文档已经加载时的window.onload值来修复它。 - iurii
哇!聪明。谢谢! - GTodorov

28

为了可靠地过滤IE8及更早版本,可以使用检查全局对象

if (document.all && !document.addEventListener) {
    alert('IE8 or lower');
}

2
document.all - 在IE 11中不受支持 - https://msdn.microsoft.com/zh-cn/library/ie/ms537434(v=vs.85).aspx - Raja Khoury
3
如果要测试 IE<9,那么这样做没问题——if条件语句将返回false。 - nnnnnn

21

使用特性检测来检测IE版本(IE6+,检测IE6之前的浏览器为6,对于非IE浏览器返回null):

var ie = (function (){
    if (window.ActiveXObject === undefined) return null; //Not IE
    if (!window.XMLHttpRequest) return 6;
    if (!document.querySelector) return 7;
    if (!document.addEventListener) return 8;
    if (!window.atob) return 9;
    if (!document.__proto__) return 10;
    return 11;
})();

编辑:我已经为您创建了一个 bower/npm 仓库,以方便您使用:ie-version

更新:

更紧凑的版本可以写成一行:

return window.ActiveXObject === undefined ? null : !window.XMLHttpRequest ? 6 : !document.querySelector ? 7 : !document.addEventListener ? 8 : !window.atob ? 9 : !document.__proto__ ? 10 : 11;

17

此函数将返回IE主要版本号作为整数,如果浏览器不是Internet Explorer,则返回undefined。像所有用户代理解决方案一样,它容易受到用户代理欺骗的影响(自IE 8版本以来已成为官方功能)。

function getIEVersion() {
    var match = navigator.userAgent.match(/(?:MSIE |Trident\/.*; rv:)(\d+)/);
    return match ? parseInt(match[1]) : undefined;
}

Owen,这个在实践中怎么使用?如何检索返回值?我尝试了 console.log(!!match && parseInt(match[1]))console.log(parseInt(match[1]))console.log(match),但是它们都没有结果。 - Frank Conijn - Support Ukraine
通过调用函数本身 getIEVersion() 来获取返回值。例如: if (getIEVersion() < 9) {/* IE 8 或更低版本 */} if (!getIEVersion()) {/* 非 IE 浏览器 */} - Owen

15

使用条件注释在JS中检测IE浏览器

// ----------------------------------------------------------
// A short snippet for detecting versions of IE in JavaScript
// without resorting to user-agent sniffing
// ----------------------------------------------------------
// If you're not in IE (or IE version is less than 5) then:
//     ie === undefined
// If you're in IE (>=5) then you can determine which version:
//     ie === 7; // IE7
// Thus, to detect IE:
//     if (ie) {}
// And to detect the version:
//     ie === 6 // IE6
//     ie > 7 // IE8, IE9 ...
//     ie < 9 // Anything less than IE9
// ----------------------------------------------------------

// UPDATE: Now using Live NodeList idea from @jdalton

var ie = (function(){

    var undef,
        v = 3,
        div = document.createElement('div'),
        all = div.getElementsByTagName('i');

    while (
        div.innerHTML = '<!--[if gt IE ' + (++v) + ']><i></i><![endif]-->',
        all[0]
    );

    return v > 4 ? v : undef;

}());

这基本上和我的答案一样。 - Tim Down
@TimDown:也许吧,但是这个答案更加完整(它告诉你版本号),而且有很好的注释。此外,这个答案开头的链接指向一个Gist,里面有几条信息丰富的评论和对这个技术的有趣变化。 - Alan
@Alan:说得好。我把我的回答针对问题进行了调整,但没有引用来源。 - Tim Down

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