简体   繁体   English

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

[英]Javascript IE detection, why not use simple conditional comments?

In order to detect IE most Javascript libaries do all sort of tricks. 为了检测IE,大多数Javascript库都做了各种各样的技巧。

  • jQuery seem to add a temporary object into your pages's DOM to detect some features, jQuery似乎在页面的DOM中添加了一个临时对象来检测某些功能,
  • YUI2 does regex on the user agent in its YAHOO.env.ua = function() (file yahoo.js ) YUI2在其YAHOO.env.ua = function() (文件yahoo.js )中对用户代理进行正则表达式

After reading this answer it came in my mind that it's true, in order to detect simply IE in Javascript we could simply add to our pages: 在阅读了这个答案之后,我想到了这是真的,为了在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>

Now the window.isIE variable is set for all our Javascript code, by simply doing: 现在,为所有Javascript代码设置window.isIE变量,只需执行以下操作:

if(window.isIE)
   ...

Beside the fact that this might result in being a pain because it has to be added in all pages, are there any issues/considerations I might be unaware of? 除了这可能导致痛苦,因为它必须在所有页面中添加之外, 是否存在我可能不知道的任何问题/考虑因素?


FYI: I know it's better to use object detection rather than browser detection , but there are cases where you still have to use browser detection. 仅供参考:我知道最好使用对象检测而不是浏览器检测 ,但有些情况下您仍然需要使用浏览器检测。

James Padolsey put a little snippet on GitHub that I'll quote here: 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;

}());

Of course all credits should go to James, I'm only the messenger (but please shoot the messenger if my copy-paste action erred). 当然所有的积分应该归詹姆斯,我只是信使(但如果我的复制粘贴动作错误,请拍摄信使)。

Also look at the forks that were created. 还要看一下创建的叉子。 Paul Irish explained the inner workings in a comment . Paul Irish在评论中解释了内部运作。

如果你想这样做,我认为使用条件编译要好得多,因为你可以在javascript内部进行,而无需更改html:

var isIE = /*@cc_on!@*/false;

Marcel Korpel's answer no longer works (in IE 10 it returns undef, so IE 10 appears as not being IE). Marcel Korpel的答案不再适用(在IE 10中它返回undef,因此IE 10看起来不是IE)。 NOTE: Now updated to work with IE 11 also. 注意:现在更新以使用IE 11。

This is a variant of that code, but which comes from Microsoft's recommendations . 这是该代码的变体,但它来自Microsoft的建议 If you were using the previous code, you can just drop in this replacement since it is built to be called the exact same way. 如果您使用的是以前的代码,则可以直接使用此替换代码,因为它的构建方式与完全相同。

Unlike conditional comments/compilation, it should also work fine with minimizers. 与条件注释/编译不同,它也应该与最小化器一起使用。

// ----------------------------------------------------------
// 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);
}());

updated to work with IE11. 更新以使用IE11。 Thanks 'acarlon' for pointing out that it wasn't working, and 'mario' for code that I based the fix on! 感谢'acarlon'指出它无法正常工作,并且'mario'代码我基于修复程序!

IE 11 has changed a lot and now many past methods of browser detection do not work. IE 11已经发生了很大的变化,现在许多过去的浏览器检测方法都不起作用。 The below code works for IE 11 and earlier. 以下代码适用于IE 11及更早版本。

function isIE()
{
    var isIE11 = navigator.userAgent.indexOf(".NET CLR") > -1;      
    var isIE11orLess = isIE11 || navigator.appVersion.indexOf("MSIE") != -1;
    return isIE11orLess;
}

I think I have what you are looking for. 我想我有你想要的东西。 You can get the Full Version of Internet Explorer as a string "AA.BB.CCCC.DDDD" using Javascript and clientCaps. 您可以使用Javascript和clientCaps将完整版本的Internet Explorer作为字符串“AA.BB.CCCC.DDDD”。

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

It appears to work for IE 5.5 and higher (including IE 10). 它似乎适用于IE 5.5及更高版本(包括IE 10)。 It is immune to the navigator.userAgent/document mode/browser mode. 它不受navigator.userAgent /文档模式/浏览器模式的影响。 There is no need for conditional comments, or any extra HTML elements. 不需要条件注释或任何额外的HTML元素。 It is a pure Javascript solution. 这是一个纯粹的Javascript解决方案。

I am not certain at this time how IE Mobile behaves, but you can always use a backup detection method in case this clientCaps method fails. 我目前还不确定IE Mobile的行为方式,但是如果此clientCaps方法失败,您总是可以使用备份检测方法。

So far, I gotta say, it works pretty well. 到目前为止,我得说,它运作得很好。

I think you answered your own question: first, it only detects IE, so the script would in essence be splitting the universe of browsers into 2 parts: IE and <everythingelse>. 我认为你回答了自己的问题:首先,它只检测IE,因此脚本本质上是将浏览器世界分为两部分:IE和<everythingelse>。

Second, you'd have to add a wacky looking comment to every HTML page. 其次,你必须为每个HTML页面添加一个古怪的评论。 Given that wide-ranging JavaScript libraries like jQuery and YUI have to be "easy" to insert/utilize for a breadth of sites, you would automatically be making them harder to use out of the gate. 鉴于像jQuery和YUI这样的广泛的JavaScript库必须“容易”插入/利用广泛的网站,你会自动使它们更难以使用。

navigator.userAgent exists if browser detection (rather than feature detection) is really needed, and jQuery uses it to get the information for the $.browser object. 如果确实需要浏览器检测(而不是特征检测),则存在navigator.userAgent ,jQuery使用它来获取$.browser对象的信息。 It's much nicer than having to include an IE-specific conditional comment in every page. 它比在每个页面中包含特定于IE的条件注释要好得多。

在这里你可以找到一些非常简单的浏览器检测黑客: http//www.thespanner.co.uk/2009/01/29/detecting-browsers-javascript-hacks/

var isIE = IE='\v'=='v';
var version = navigator.userAgent.match(/(msie) (\d+)/i);
console.log(version);

something quick I wrote quick after looking at this question in case anyone wants it. 在看到这个问题之后我快速写了一些东西以防万一有人想要它。

** EDIT ** **编辑**

Per Johnny Darvall's comment below, I'm adding a link for anyone who is trying to sniff out Internet Explorer 11 : 根据Johnny Darvall的评论,我正在为试图嗅出Internet Explorer 11的人添加一个链接:

http://blogs.msdn.com/b/ieinternals/archive/2013/09/21/internet-explorer-11-user-agent-string-ua-string-sniffing-compatibility-with-gecko-webkit.aspx http://blogs.msdn.com/b/ieinternals/archive/2013/09/21/internet-explorer-11-user-agent-string-ua-string-sniffing-compatibility-with-gecko-webkit.aspx

I'm using that code 我正在使用该代码

var isIE = navigator.userAgent.indexOf(' MSIE ') > -1; var isIE = navigator.userAgent.indexOf('MSIE')> -1;

Checking for browsers is a bad idea - it's better to check for browser features instead. 检查浏览器是一个坏主意 - 最好检查浏览器功能 For example, usually you check if the user is using IE because you want to use some feature not supported in IE. 例如,通常您检查用户是否使用IE,因为您想使用IE中不支持的某些功能。 However, can you know ALL current and future non-IE browsers will support that feature? 但是,您能否知道所有当前和未来的非IE浏览器都支持该功能? No. So the way eg used by jQuery is better: It creates and executes small testcases checking for certain bugs/features - and you can simply check stuff like if(browser_supports_XYZ) instead of checking if the user is using a specific browser. 不。所以jQuery使用的方式更好:它创建并执行小型测试用例,检查某些错误/功能 - 你可以简单地检查if(browser_supports_XYZ)等内容,而不是检查用户是否使用特定的浏览器。

Anyway, there are always cases where checking for the browser is necessary because it's a visual bug you cannot test for using a script. 无论如何,总是有必要检查浏览器是必要的,因为它是一个你无法使用脚本测试的可视错误。 In this case it's better to use javascript instead of conditional comments because you have the browser check right at the position where you need it instead of at some other place (imagine a .js file where you check for isIE which is never defined in that file) 在这种情况下,最好使用javascript而不是条件注释,因为您可以在需要它的位置检查浏览器而不是在其他位置(想象一个.js文件,在那里检查isIE,它永远不会在该文件中定义)

For my use case, I really just need to detect if lower than IE9, so I use 对于我的用例,我真的只需要检测是否低于IE9,所以我使用

if (document.body.style.backgroundSize === undefined && navigator.userAgent.indexOf('MSIE') > -1)
{
//IE8- stuff
}

Why don't you just program in HTML5, and check that 你为什么不用HTML5编程,然后检查一下

if ( window.navigator.product !== "Gecko" )

?? ?? True, this will include IE11 in the "Gecko" bunch, but isn't it supposed to be good enough now? 没错,这将包括IE11在“Gecko”中的一堆,但它现在不应该足够好吗?

Note: the HTML5 spec. 注意:HTML5规范。 says that navigator.product must return "Gecko"... and IE10 and earlier all return something else. 说navigator.product必须返回“Gecko”...... IE10和之前的所有内容都会返回其他内容。

  • It pollutes global namespace 它会污染全局命名空间
  • It requires changes in two files. 它需要更改两个文件。
  • It works in IE only 它仅适用于IE
  • Technically, a conditional comment is still a comment 从技术上讲,条件评论仍然是评论

这非常有效,
var isIe = !!window.ActiveXObject;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM