【问题标题】:How to detect Internet Explorer in JavaScript with Google Closure Compiler?如何使用 Google Closure Compiler 检测 JavaScript 中的 Internet Explorer?
【发布时间】:2011-02-26 16:03:20
【问题描述】:

我有一个处理鼠标按钮事件的 JavaScript 函数。它必须能够区分鼠标左键和右键。遗憾的是,Internet Explorer 对 event.button 使用的值与所有其他浏览器不同。我知道如何解释它们,但我需要知道该走哪条路。

我通过依赖条件编译的 JavaScript hack 做到了这一点。是这样的:

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

我认为这是一种相当安全的方法,因为它基于 JavaScript 解析器功能,无法伪造,也不太可能被其他浏览器模仿。

现在我正在使用 Google Closure Compiler 来打包我的 JavaScript 文件。我发现它也像任何其他评论一样删除了条件编译 cmets。所以我尝试了不同的技巧。其中之一是这样的:

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

不幸的是,闭包编译器非常聪明,发现条件永远不会为真并删除该代码。另外,我不喜欢它,因为微软最终可能会修复那个 \v 错误,然后检测失败。

我可以只阅读类似 navigator.appName 或它的名称之类的内容,但这太容易伪造了。如果有人修改了他们的浏览器标识,他们不太可能实现其他 event.button 行为......

闭包编译器允许保留某些 cmets。我试过这个:

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

虽然这会在压缩后产生所需的结果,但它不是源形式的功能性条件注释。但出于调试原因,我需要我的 JavaScript 文件在压缩和未压缩的情况下都可以工作。

我有没有希望在不手动修改压缩的 JS 文件的情况下让它工作?

作为参考,这是我的完整函数的原始形式:

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

【问题讨论】:

    标签: javascript cross-browser conditional-compilation google-closure-compiler


    【解决方案1】:

    脚本开头有两行似乎已经检测到浏览器是否为 IE。为什么不将其用作 if 语句的基础:

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

    【讨论】:

    • event.srcElement 的存在是检测 IE 的确定条件吗?我完全没有这方面的细节。 srcElement/target 代码适用于该单行(检测功能,而不是浏览器),但可能会在其他任何地方失败。不幸的是,特征检测无法解释 event.button 的值。
    【解决方案2】:

    你可以有一个 separate 脚本来设置一个全局(如 jQuery ".browser()" 事物),并将它包含在条件注释中:

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

    事实上,你可以让它变得更漂亮:

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

    然后在您压缩的“真实”脚本中,您可以这样做:

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

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

    【讨论】:

      【解决方案3】:

      你可以这样做:

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

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

      【讨论】:

        【解决方案4】:
        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)) {
            // ...
        }
        

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

        【讨论】:

        • 澄清了我的问题,因为我的旧问题得到了多个不相关的答案。我说的是闭包编译器,而不是同名的库(如果存在这样的东西,我从来没有关心过也没有使用过)。
        【解决方案5】:

        好的,经过一番搜索,现在我对这个解决方案很满意:

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

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

        以下是我在途中发现的其他方法的列表:
        http://dean.edwards.name/weblog/2007/03/sniff/ – 不适用于 Closure Compiler
        http://webreflection.blogspot.com/2009/01/32-bytes-to-know-if-your-browser-is-ie.html – 那是带有 "\v "
        http://www.thespanner.co.uk/2009/01/29/detecting-browsers-javascript-hacks/ – 与上述类似,也适用于其他浏览器
        How to detect Internet Explorer in JavaScript with Google Closure Compiler? – John 在此页面上的回答

        【讨论】:

          【解决方案6】:

          只是偶然发现了这一点,所以这是 2013 年的更新答案:

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

          如果您需要特定于版本:

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

          Docs

          【讨论】:

          • 我没有使用 Closure library,而只使用了 compiler。所以我需要编译时支持,而不是运行时。事实上,我的 Js 库在某种程度上是一个非常简单的闭包库版本。
          • 啊,好吧。好吧,我将把它留在这里以防万一有人想知道如何使用图书馆。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-04-21
          • 2015-10-23
          • 1970-01-01
          • 1970-01-01
          • 2010-12-14
          • 2012-05-10
          • 2019-09-27
          相关资源
          最近更新 更多