Javascript IE 检测,为什么不使用简单的条件注释?

IT技术 javascript internet-explorer browser-detection conditional-comments
2021-01-30 22:39:42

为了检测 IE,大多数 Javascript 库会使用各种技巧。

  • jQuery 似乎在页面的 DOM 中添加了一个临时对象来检测某些功能,
  • YUI2 在其YAHOO.env.ua = function()(文件yahoo.js)中的用户代理上执行正则表达式

阅读完这个答案后,我想到这是真的,为了在 Javascript 中简单地检测 IE,我们可以简单地添加到我们的页面:

<!--[if IE]><script type="text/javascript">window['isIE'] = true;</script><![endif]-->

<script type="text/javascript" src="all-your-other-scripts-here.js"></script>

现在window.isIE为我们所有的 Javascript 代码设置变量,只需执行以下操作:

if(window.isIE)
   ...

除了这可能会导致痛苦,因为它必须添加到所有页面之外,还有什么我可能不知道的问题/注意事项吗?


仅供参考:我知道最好使用对象检测而不是浏览器检测,但在某些情况下您仍然必须使用浏览器检测。

6个回答

James Padolsey在 GitHub上放了一个小片段,我将在这里引用:

// ----------------------------------------------------------
// 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;

}());

当然,所有的功劳都应该归詹姆斯所有,我只是信使(但如果我的复制粘贴操作出错,请向信使开枪)。

还要查看创建的分叉。Paul Irish 在评论中解释了内部运作

IE10 不再支持条件语句
2021-03-30 22:39:42
我喜欢这个功能,所以我在下面创建了一个版本,它可以在 IE10 中运行,并以相同的方式调用,以便其他使用它的人可以直接替换。
2021-03-31 22:39:42
不再支持 HTML 中的条件注释(例如<!--[if IE]><![endif]-->),而不支持IE10 中的条件语句。
2021-04-13 22:39:42

如果你想这样做,我认为使用条件编译会更好,因为你可以在 javascript 中执行它而无需更改 html:

var isIE = /*@cc_on!@*/false;
@AlfonsoML 那是什么奇怪的黑客?:)
2021-03-14 22:39:42
我在 Windows 7 和 8 上的 IE10 上尝试过,但没有奏效。
2021-03-17 22:39:42
@AlfonsoML 多年来,我一直在阅读有关条件注释和 userAgent 字符串的信息,现在您告诉我您可以用这一行检测 IE 吗?:p
2021-03-19 22:39:42
这有效。但是,与条件注释不同的是,条件编译无法区分 IE 的版本,只能区分不同版本的 JScript 引擎(可以独立于 IE 版本进行交换和替换)。
2021-04-11 22:39:42
请记住,minifyers 不喜欢这样的想法;YUI Compressor 生气,Google Closure Compiler 噎死。
2021-04-12 22:39:42

Marcel Korpel 的回答不再有效(在 IE 10 中它返回 undef,因此 IE 10 看起来不是 IE)。注意:现在更新后也可以与 IE 11 一起使用。

这是该代码的变体,但来自Microsoft 的建议如果您使用的是以前的代码,则可以直接删除此替换代码,因为它的构建方式是完全相同的。

与条件注释/编译不同,它也应该与最小化器一起正常工作。

// ----------------------------------------------------------
// 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, IE10 ...
// ie < 9 // Anything less than IE9
// ----------------------------------------------------------
var ie = (function(){
    var undef,rv = -1; // Return value assumes failure.
    var ua = window.navigator.userAgent;
    var msie = ua.indexOf('MSIE ');
    var trident = ua.indexOf('Trident/');

    if (msie > 0) {
        // IE 10 or older => return version number
        rv = parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10);
    } else if (trident > 0) {
        // IE 11 (or newer) => return version number
        var rvNum = ua.indexOf('rv:');
        rv = parseInt(ua.substring(rvNum + 3, ua.indexOf('.', rvNum)), 10);
    }

    return ((rv > -1) ? rv : undef);
}());

更新以使用 IE11。感谢 'acarlon' 指出它不起作用,感谢 'mario' 指出我基于修复的代码!

这不再适用于 IE11,因为 navigator.appName 不是 M$。这个答案虽然有效:stackoverflow.com/a/21712356/746754
2021-03-23 22:39:42
但这适用于 User-Agent 字符串嗅探;UA 字符串很容易被欺骗,但条件注释不能。无论如何,谁需要检测 IE 10?如今,您可以使用特征检测来测试所有内容,这远优于浏览器检测(仅需要检测无法通过特征检测检测到的事物)。
2021-03-29 22:39:42
@Marcel 如果你想假装成别人,请随意。这应该可以帮助普通的 IE 白痴(他们不会进行欺骗)。如果你想假装,那不会伤害任何人,除了(可能)你自己。
2021-04-06 22:39:42
@MarcelKorpel:“if(ie){}”在 IE 10 中返回 false 是非常具有误导性的,因为它IE。关于欺骗,这是真的。我认为在大多数情况下(除安全相关问题外的所有情况),如果用户想要欺骗用户代理,那么可以响应他们选择代表自己的 UA。在我的特定用例中,我正在与 Trello 的 API 交互,其“弹出”身份验证目前在任何版本的 IE(包括 IE10)中都不起作用,因此如果(即),我选择使用不同的方法(使用更少的最佳用户界面,但至少它适用于 IE)。
2021-04-08 22:39:42
这对我有帮助,因为我特别需要检测 IE 10。
2021-04-10 22:39:42

IE 11 发生了很大变化,现在许多过去的浏览器检测方法都不起作用。以下代码适用于 IE 11 及更早版本。

function isIE()
{
    var isIE11 = navigator.userAgent.indexOf(".NET CLR") > -1;      
    var isIE11orLess = isIE11 || navigator.appVersion.indexOf("MSIE") != -1;
    return isIE11orLess;
}
这看起来很不错,但是为什么要使用“.NET CLR”而不是“Trident”?
2021-03-19 22:39:42
谢谢,我用它来 alert() 然后将 IE 用户重定向到browsehappy.com :) 对于个人网络应用程序,一个替代的 Steam 库:sam.nipl.net/free-games.html 我不想去通过目前让它在 IE 中工作的痛苦!
2021-03-20 22:39:42
这是迄今为止我最喜欢的答案。它有效且简洁。谢谢@webber55
2021-03-22 22:39:42
@Ligntningsoul:搜索“.NET CLR”强调这是一项微软技术,在不久的将来不太可能改变。
2021-03-23 22:39:42

我想我有你要找的东西。您可以使用 Javascript 和 clientCaps 以字符串“AA.BB.CCCC.DDDD”的形式获取 Internet Explorer 的完整版本。

http://www.pinlady.net/PluginDetect/IE/

它似乎适用于 IE 5.5 及更高版本(包括 IE 10)。它不受 navigator.userAgent/document mode/browser mode 的影响。不需要条件注释或任何额外的 HTML 元素。它是一个纯 Javascript 解决方案。

我目前不确定 IE Mobile 的行为方式,但您始终可以使用备份检测方法,以防此 clientCaps 方法失败。

到目前为止,我得说,它运行得很好。