Как обнаружить Internet Explorer в JavaScript с помощью компилятора Google Closure? - PullRequest
3 голосов
/ 26 февраля 2011

У меня есть функция JavaScript, которая обрабатывает события кнопки мыши. Он должен уметь различать левую и правую кнопки мыши. К сожалению, Internet Explorer использует другие значения для event.button, чем все другие браузеры. Я знаю, как их интерпретировать, но мне нужно знать, по какому пути идти.

Я сделал это с помощью хака JavaScript, который опирается на условную компиляцию. Это так:

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

Я считаю, что это довольно безопасный метод, поскольку он основан на возможностях парсера JavaScript, которые не могут быть подделаны и вряд ли будут имитироваться другими браузерами.

Теперь я использую компилятор Google Closure, чтобы упаковать мои файлы JavaScript. Я обнаружил, что он удаляет комментарии условной компиляции, как и любой другой комментарий. Поэтому я пробовал разные хаки. Один из них это это:

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

К сожалению, компилятор замыкания довольно умен и обнаруживает, что условие никогда не может быть истинным, и удаляет этот код. Кроме того, мне это не нравится, потому что Microsoft может в конечном итоге исправить эту ошибку \ v, а затем обнаружение не удастся.

Я мог бы просто прочитать что-то вроде navigator.appName или как оно называется, но это слишком легко подделать. И если кто-то изменяет идентификацию своего браузера, он вряд ли реализует другое поведение event.button ...

Закрытие компилятора позволяет сохранить определенные комментарии. Я попробовал это:

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

Ответы [ 6 ]

2 голосов
/ 04 марта 2011

Вы можете сделать это:

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

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

2 голосов
/ 26 февраля 2011

У вас может быть отдельный сценарий, который устанавливает глобальный объект (например, 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 */ }
2 голосов
/ 26 февраля 2011

У вас есть две строки в начале вашего скрипта, которые, кажется, уже определяют, является ли браузер IE.Почему бы не использовать это в качестве основы для вашего заявления if:

var IE = (!e.target && e.srcElement);
if (IE)  {
    !e.target && e.srcElement
}
// ...
if (IE) {
    if (e.button & 1)
        e.mouseButton = 0;
    // ...
1 голос
/ 03 декабря 2013
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

0 голосов
/ 26 ноября 2013

Просто наткнулся на это, поэтому вот обновленный ответ за 2013 год:

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

А если вам нужно быть привязанным к версии:

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

Документы

0 голосов
/ 05 марта 2011

Хорошо, после еще нескольких поисков, сейчас я доволен этим решением:

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
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/ -Как и выше, также для других браузеров
Как обнаружить Internet Explorer в JavaScript с помощью Google Closure Compiler? - Ответ Джона на этой странице

...