开发者

How to detect Internet Explorer in JavaScript with Google Closure Compiler?

I have a JavaScript function that handles mouse button events. It must be able to distinguish between left and right mouse buttons. Sadly, Internet Explorer uses different values for event.button than all other browsers do. I know how to interpret them, but I need to know which path to go.

I did that with a JavaScript hack that relies on conditional compilation. It's like this:

if (/*@cc_on!@*/false) { IE fixup... }

I consider this quite a safe method because it is based on the JavaScript parser capabilities that cannot be faked and are unlikely to be imitated by other browsers.

Now I'm using the Google Closure Compiler to pack my JavaScript files. I found that it removes conditional compilation comments just like any other comment, too. So I tried different hacks. One of them it this:

if ("\v" == "v") { IE fixup... }

Unfortunately, the closure compiler quite clever and finds out that the condition can never be true and removes that code. Also, I don't like it because Microsoft may eventually fix that \v bug and then the detection fails.

I could just read something like navigator.appName or what it's called, but this is way too easy to fake. And if somebody modifies their browser identification, they're unlikely to implement the other event.button behaviour...

Closure compiler allows to preserve certain comments. I tried this:

if (/**@preserve/*@cc_on!@*/false) { IE fixup... }

While this produces the desired result after compression, it is not a functional conditional comment in its source form. But for debugging reasons, I need my JavaScript file to work both compressed and uncompressed.

Is there any hope for me to get this working without modifying the compressed JS file by hand?

For the r开发者_开发技巧eference, here's my complete function in its original form:

function findEvent(e)
{
    e = e || event;   // IE
    if (!e.target && e.srcElement)   // IE
        e.target = e.srcElement;
    if (isSet(e.button))
    {
        // Every browser uses different values for the mouse buttons. Correct them here.
        // DOM says: 0 = left, 1 = middle, 2 = right (multiple buttons not supported)
        // Opera 7 and older and Konqueror are not specifically handled here.
        // See http://de.selfhtml.org/javascript/objekte/event.htm#button
        if (/*@cc_on!@*/false)   // IE - http://dean.edwards.name/weblog/2007/03/sniff/ - comment removed by Google Closure Compiler
        {
            if (e.button & 1)
                e.mouseButton = 0;
            else if (e.button & 2)
                e.mouseButton = 2;
            else if (e.button & 4)
                e.mouseButton = 1;
        }
        else
            e.mouseButton = e.button;
    }
    return e;
}


You have two lines at the beginning of your script which seem to already detect if the browser is IE. Why not use that as a base for your if statement :

var IE = (!e.target && e.srcElement);
if (IE)  {
    !e.target && e.srcElement
}
// ...
if (IE) {
    if (e.button & 1)
        e.mouseButton = 0;
    // ...


You could have a separate script that sets up a global (like the jQuery ".browser()" thing), and have it be included by conditional comment:

<!--[if IE]>
<script>
  window.isIe = true;
</script>
<[endif]-->

In fact you could make this even fancier:

<!--[if = IE 6]>
<script>
  window.isIe = { version: 6 };
</script>
<[endif]-->

<!--[if = IE 7]>
<script>
  window.isIe = { version: 7 };
</script>
<[endif]-->

<!--[if = IE 8]>
<script>
  window.isIe = { version: 8 };
</script>
<[endif]-->

Then in your compressed "real" script you can just do:

if (isIe) { /* IE stuff */ }

and

if (isIe && isIe.version === 6) { /* IE6 stuff */ }


You can do this:

var is_ie = eval("/*@cc_on!@*/false");

http://code.google.com/p/closure-compiler/wiki/UsingConditionalCommentWithClosureCompiler


if (goog.userAgent.IE) {
    // run away
};

/**
 * Condition will be true for IE < 9.0
 * @see goog.string.compareVersions
 */
if (goog.userAgent.IE && goog.userAgent.compare(9, goog.userAgent.VERSION) == 1) {
    // run away even faster
}

/**
 * Condition will be true for IE >= 10.0
 */
if (goog.userAgent.IE && goog.userAgent.isVersionOrHigher(10)) {
    // ...
}

source : http://www.closurecheatsheet.com/other#goog-useragent


Okay, after some more searching, for now I'm happy with this solution:

function ieVersion()
{
    var style = document.documentElement.style;
    if (style.scrollbar3dLightColor != undefined)
    {
        if (style.opacity != undefined)
            return 9;
        else if (style.msBlockProgression != undefined)
            return 8;
        else if (style.msInterpolationMode != undefined)
            return 7;
        else if (style.textOverflow != undefined)
            return 6;
        else
            return 5.5;
    }
    return 0;
}

Found on http://msdn.microsoft.com/en-us/library/ms537509%28v=vs.85%29.aspx#4

Here's a list of other methods I found on the way:
http://dean.edwards.name/weblog/2007/03/sniff/ – Doesn't work with Closure Compiler
http://webreflection.blogspot.com/2009/01/32-bytes-to-know-if-your-browser-is-ie.html – That's the one with "\v"
http://www.thespanner.co.uk/2009/01/29/detecting-browsers-javascript-hacks/ – Similar to above, also for other browsers
How to detect Internet Explorer in JavaScript with Google Closure Compiler? – Answer by John on this page


Just stumbled on this, so here's an updated answer for 2013:

if (goog.userAgent.IE) { ... }

And if you need to be version-specific:

if (goog.userAgent.IE && goog.userAgent.VERSION != '10.0') { ... }

Docs

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜