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

血红的双手。 提交于 2019-12-17 03:25:08

问题


In order to detect IE most Javascript libaries do all sort of tricks.

  • jQuery seem to add a temporary object into your pages's DOM to detect some features,
  • YUI2 does regex on the user agent in its YAHOO.env.ua = function() (file 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:

<!--[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:

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.


回答1:


James Padolsey put a little snippet on GitHub that I'll quote here:

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




回答2:


If you want to do it that way, I think it's much better to use Conditional Compilation instead as you can do it inside the javascript without requiring to change the html:

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



回答3:


Marcel Korpel's answer no longer works (in IE 10 it returns undef, so IE 10 appears as not being IE). NOTE: Now updated to work with IE 11 also.

This is a variant of that code, but which comes from Microsoft's recommendations. 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. Thanks 'acarlon' for pointing out that it wasn't working, and 'mario' for code that I based the fix on!




回答4:


IE 11 has changed a lot and now many past methods of browser detection do not work. The below code works for IE 11 and earlier.

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



回答5:


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.

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

It appears to work for IE 5.5 and higher (including IE 10). It is immune to the navigator.userAgent/document mode/browser mode. There is no need for conditional comments, or any extra HTML elements. It is a pure Javascript solution.

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.

So far, I gotta say, it works pretty well.




回答6:


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>.

Second, you'd have to add a wacky looking comment to every HTML page. 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.




回答7:


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. It's much nicer than having to include an IE-specific conditional comment in every page.




回答8:


Here you can find some really simple hacks for browser-detecting: http://www.thespanner.co.uk/2009/01/29/detecting-browsers-javascript-hacks/

var isIE = IE='\v'=='v';



回答9:


I'm using that code

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




回答10:


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:

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




回答11:


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. However, can you know ALL current and future non-IE browsers will support that feature? No. So the way e.g. 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.

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)




回答12:


For my use case, I really just need to detect if lower than IE9, so I use

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



回答13:


  • It pollutes global namespace
  • It requires changes in two files.
  • It works in IE only
  • Technically, a conditional comment is still a comment



回答14:


This works quite well,
var isIe = !!window.ActiveXObject;




回答15:


Why don't you just program in HTML5, and check that

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

?? True, this will include IE11 in the "Gecko" bunch, but isn't it supposed to be good enough now?

Note: the HTML5 spec. says that navigator.product must return "Gecko"... and IE10 and earlier all return something else.



来源:https://stackoverflow.com/questions/4169160/javascript-ie-detection-why-not-use-simple-conditional-comments

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!