Самая простая / легкая замена для обнаружения браузера jQuery 1.9?

Вчера у меня было несколько клиентов, которые жаловались, что какой-то код перестал работать. По-видимому, это сводится к плагинам, использующим ныне устаревший jQuery.browser, который перестал работать вчера, когда был выпущен jQuery 1.9.

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

Есть ли рекомендуемый самый легкий плагин или фрагмент кода для восстановления этой функциональности?

Для того, что нужно этим сайтам, это очень просто; Мне нужно только самое базовое определение IE, FF и всех остальных.

Предложения?


person jchwebdev    schedule 16.01.2013    source источник
comment
Чтобы процитировать сообщение пятилетней давности из документов jQuery: мы не рекомендуем использовать это свойство; попробуйте вместо этого использовать обнаружение функций (см. jQuery.support). jQuery.browser может быть перемещен в плагин в будущем выпуске jQuery. api.jquery.com/jQuery.browser VS. api.jquery.com/jQuery.support   -  person feeela    schedule 16.01.2013
comment
используйте >1.8 ,<1.9 меньший jQuery.   -  person Jai    schedule 16.01.2013
comment
Спасибо. Я понимаю, что он был помечен как устаревший. У меня есть несколько плагинов, которые зависят от свойства .offsetTop, которое возвращает разные значения для разных браузеров. Я обнаружил, что простая проверка IE, Mozilla и Chrome была простым обходным путем. Если бы offsetTop был последовательным, мне бы это вообще не понадобилось.   -  person jchwebdev    schedule 17.01.2013


Ответы (13)


Я использую следующий код, на который ответил Alexx Roche, но я хотел обнаружить MSIE, поэтому:

<script type="text/javascript">
   $(document).ready(function() {
      if (navigator.userAgent.match(/msie/i) ){
        alert('I am an old fashioned Internet Explorer');
      }
   });
</script>

Надеюсь, поможет!

person Fede    schedule 24.04.2013
comment
Если вы хотите поймать и более новые IE:s, добавьте проверку на трезубец, например так: if (navigator.userAgent.match(/msie|trident/i)) {;} - person Martin Andersson; 30.11.2013

jQuery Migrate был создан для обеспечить обратную совместимость при обновлении кода.

https://github.com/jquery/jquery-migrate

В качестве бонуса он регистрирует устаревшие функции по мере их использования. Я бы попробовал, пока вы решаете проблемы. Кроме того, вы должны установить определенную версию jQuery для своих сайтов. Обновление — это хорошо, но обязательно протестируйте эти обновления, прежде чем запускать их в производство. Если вы используете CDN, вы все равно можете указать конкретную версию в имени файла.

Теперь вам не нужен подключаемый модуль jQuery для того, о чем вы просите. Ознакомьтесь с объектом navigator.

appCodeName: "Mozilla"
appName: "Netscape"
appVersion: "5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.52 Safari/537.17"
cookieEnabled: true
doNotTrack: null
geolocation: Geolocation
language: "en-US"
mimeTypes: MimeTypeArray
onLine: true
platform: "MacIntel"
plugins: PluginArray
product: "Gecko"
productSub: "20030107"
userAgent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.52 Safari/537.17"
vendor: "Google Inc."
vendorSub: ""
person Brad    schedule 16.01.2013
comment
Спасибо. Я, пожалуй, воспользуюсь навигатором. Некоторые из моих клиентов — это сайты, которые я перенял у других разработчиков, и это то, что ускользает от внимания. (Мои трещины, во всяком случае). - person jchwebdev; 17.01.2013
comment
Следующий глупый вопрос... Я только что попробовал Navigator в Firebug и Chrome Console. И оба показывают Netscape как appName и Mozilla как appCodeName. А «Поставщик» — это Mozilla в FF, но пусто в Chrome. Итак ... есть ли простой "трюк" или это (еще одна) довольно сложная тема без 2-3 строк кода? - person jchwebdev; 17.01.2013
comment
Вы также должны попробовать использовать кнопку «принять ответ» время от времени. - person teynon; 17.01.2013
comment
@jchwebdev, я бы посмотрел на navigator.userAgent. Должно быть достаточно легко увидеть, содержит ли строка то, что вы ищете. (Не ищите точных совпадений, так как очевидно, что номера версий и плагины меняются.) - person Brad; 17.01.2013
comment
Спасибо, Брэд. Я был немного расстроен ранее. Я думал, что весь хлам с «войной браузеров» в основном закончился. - person jchwebdev; 17.01.2013
comment
var browser = { chrome: ложь, mozilla: ложь, опера: ложь, msie: ложь, сафари: ложь}; var sBrowser, sUsrAg = navigator.userAgent; if(sUsrAg.indexOf(Chrome) › -1) { browser.chrome = true; } else if (sUsrAg.indexOf(Safari) › -1) { browser.safari = true; } else if (sUsrAg.indexOf(Opera) › -1) { browser.opera = true; } else if (sUsrAg.indexOf(Firefox) › -1) { browser.mozilla = true; } else if (sUsrAg.indexOf(MSIE) › -1) { browser.msie = true; } console.log(browser.msie); - person user989952; 07.05.2013

Поместите этот код на свой сайт (например, файл js или после кода jQuery...):

var matched, browser;

// Use of jQuery.browser is frowned upon.
// More details: http://api.jquery.com/jQuery.browser
// jQuery.uaMatch maintained for back-compat
jQuery.uaMatch = function( ua ) {
    ua = ua.toLowerCase();

    var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) ||
        /(webkit)[ \/]([\w.]+)/.exec( ua ) ||
        /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) ||
        /(msie) ([\w.]+)/.exec( ua ) ||
        ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) ||
        [];

    return {
        browser: match[ 1 ] || "",
        version: match[ 2 ] || "0"
    };
};

matched = jQuery.uaMatch( navigator.userAgent );
browser = {};

if ( matched.browser ) {
    browser[ matched.browser ] = true;
    browser.version = matched.version;
}

// Chrome is Webkit, but Webkit is also Safari.
if ( browser.chrome ) {
    browser.webkit = true;
} else if ( browser.webkit ) {
    browser.safari = true;
}

jQuery.browser = browser;
person Synthy    schedule 24.01.2013
comment
Этот ответ был бы улучшен, если бы он ссылался на поддерживаемый источник и отметив, что он имеет лицензию MIT. - person Brian M. Hunt; 08.02.2013
comment
Я полагаю, что это хорошо для очков и репутации, но советовать людям копировать/вставить устаревшую функциональность не решает проблем, из-за которых мы устарели $.browser в первую очередь. И да, копия/паста должны соблюдать условия лицензирования. - person Dave Methvin; 10.02.2013
comment
Я добавил небольшое исправление для обнаружения IE11 в код @Synthy. // hofix for IE11 detection var isIE11 = !!navigator.userAgent.match(/Trident\/7\./); if (isIE11) { browser.msie = "true"; delete browser.mozilla; } - person chris; 14.11.2013
comment
@DaveMethvin Это, безусловно, правда, но когда вы просто хотите, чтобы какой-то другой простой плагин работал, и вам не хочется выяснять, что делает этот плагин, для работы которого требуется .browser, это определенно самое простое исправление. (Включение всего jquery.migrate является излишним, а также имеет другие странные побочные эффекты, которые мне тоже не хочется пытаться понять, почему это происходит. Это все, что мне было нужно!) - person neminem; 16.11.2013

Я использовал следующий код, когда столкнулся с той же проблемой:

<script type="text/javascript">
 $(document).ready(function() {
    //if (!$.browser.webkit && ! $.browser.mozilla) { //depricated
    if (!navigator.userAgent.match(/mozilla/i) && 
        ! navigator.userAgent.match(/webkit/i) ){
        alert('Let me tell you about Mozilla');
    }
 });
</script>
person Alexx Roche    schedule 24.02.2013
comment
что именно это должно проверять? потому что (!navigator.userAgent.match(/mozilla/i) && !navigator.userAgent.match(/webkit/i)) ложно в IE, Chrome и Mozilla - person Matus; 09.06.2013
comment
Да, потому что в этой ситуации мне нужна была только функциональность jQuery в браузерах, которые ее поддерживали. Потянув за рычаг (!) или изменив && на || должно быть достаточно легко для тех, кто по локоть в jQuery? - person Alexx Roche; 10.06.2013
comment
нет проблем, я просто был удивлен, что отмеченный ответ не ответил на вопрос ОП - person Matus; 10.06.2013

Вы можете просто не обновляться, пока не откажетесь от устаревших методов.

Вы действительно не должны включать jquery из CDN без указания номера версии в любом случае, это в некотором смысле противоречит цели использования CDN (без кэширования).

Вот ссылка на последнюю версию jQuery, поддерживающую $.browser:

http://code.jquery.com/jquery-1.8.3.min.js

просто замените ваш jquery.js src этой ссылкой, и ваш код будет продолжать работать до тех пор, пока вы не будете готовы двигаться вперед и перестанете использовать устаревшие функции.

Примечание: Fancybox2 по-прежнему использует $.browser, это самый распространенный вариант, который я видел с момента обновления.

Обновление: Slickgrid все еще использует $.browser, обновлений по состоянию на 11.02.2013 нет.

person Kevin B    schedule 16.01.2013
comment
версии -latest и версии с подстановочными знаками больше не будут обновляться, вы не должны их больше использовать. - person Kevin B; 25.07.2014

Я абстрагировал логику от jQuery.browser в плагин jquery.browser. Плагин выпущен под лицензией MIT.

Я также добавил поддержку обнаружения IE11, Opera Webkit и Android.

person Gabriel Cebrian    schedule 26.08.2013
comment
Спасибо. Я только что собрал свой собственный плагин из исходного кода jQuery до версии 1.9, а затем нашел ваш, который имеет полезные расширения и в то же время является идеальной заменой оригинальной функциональности. - person Lambart; 15.12.2013

Попробуйте Conditionizr.

Надеюсь это поможет :)

person Ijas Ameenudeen    schedule 11.04.2013

Точную версию IE можно определить путем дополнительной проверки наличия стандартных глобальных объектов, добавленных в определенные версии IE.

10 or older document.all
9 or older  document.all && !window.atob
8 or older  document.all && !document.addEventListener
7 or older  document.all && !document.querySelector
6 or older  document.all && !window.XMLHttpRequest
5.x document.all && !document.compatMode

if (document.all && !document.querySelector) {
    alert('IE7 or lower');
}

Эти тесты избегают использования userAgent, который используется для спуфинга.

person Vincent Gloaguen    schedule 10.07.2014

if(!$.browser){
    $.browser={chrome:false,mozilla:false,opera:false,msie:false,safari:false};
    var ua=navigator.userAgent;
        $.each($.browser,function(c,a){
        $.browser[c]=((new RegExp(c,'i').test(ua)))?true:false;
            if($.browser.mozilla && c =='mozilla'){$.browser.mozilla=((new RegExp('firefox','i').test(ua)))?true:false;};
            if($.browser.chrome && c =='safari'){$.browser.safari=false;};
        });
};

http://jsfiddle.net/R3AAX/3/

person etb    schedule 21.05.2013
comment
Для полноты подключаемые модули jQuery должны ссылаться на «jQuery», а не на «$», поскольку другие библиотеки могут перезаписать ярлык $. - person Ben Hull; 03.09.2013

Если все, что вам нужно, это чтобы ваши сторонние плагины jQuery могли использовать jQuery.browser.msie, вот одна строка. Просто включите его после jQuery.

jQuery.browser = jQuery.browser || {msie: navigator.userAgent.match(/msie/i) ? true : false};

Это самое глупое из возможных исправлений, но это все, что мне было нужно, и оно действительно работает, так что вот!

person Ben Hull    schedule 03.09.2013

Чтобы добавить к этому обсуждению. Я только что придумал плагин jquery $.browser, который вместо «обнаружения» просто анализирует пользовательский агент в простой в использовании объект. Дальнейшая логика может быть легко применена для дальнейшего анализа и разбора конкретных браузеров и платформ.

У меня есть очень надежные результаты по юзерагентам, найденным здесь: UserAgentString.com. Я даже включил определение версии для ie11 (внизу).

//The following code is by no means perfect, nor is it meant to be a standalone 'detection' plugin. 
//It demonstrates parsing the useragent string into an easy to manage object. 
//Even if it does make detection rediculously easy.. :)

//Because this regex makes no assumptions in advance.
//IMO, It's compatibilty and maintainability is much higher than those based on static identifiers.

/*
  uaMatch replacement that parses a useragent string into an object
  useragent segments can be Name Value OR Name/Value OR Name

  Segment: Name Value
    Name: parsed to the last whitespace character
    Value: value after the last whitespace character
    Matches: (.NET CLR) (#.##), Android 2.3.4, etc
    Note: this regex can have leading/trailing whitespace (trimmed for object properties)

  Segment: Name/Value
    Matches: all values matching Name/Value
    Example: Firefox/24.0, Safari/533.1, Version/12.1, etc

  Segment: Name
    Matches: identifiers that hold no values (value of 'true' is implied)
    Example: Macintosh, Linux, Windows, KHTML, U, etc


   WARNING: not necessarily compatible with jQuery's $.browser implementation.
   - not recommended as a replacement for plugins that require it to function.
*/
(function ($) {

    var ua = navigator.userAgent.toLowerCase();

    var regex = /compatible; ([\w.+]+)[ \/]([\w.+]*)|([\w .+]+)[: \/]([\w.+]+)|([\w.+]+)/g;
    var match = regex.exec(ua);

    var browser = { };

    while (match != null) {
        var prop = {};

        if (match[1]) {
          prop.type = match[1];
          prop.version = match[2];
        }
        else if (match[3]) {
          prop.type = match[3];
          prop.version = match[4];
        }
        else {
          prop.type = match[5];
        }

        // some expressions have leading whitespace (i couldn't avoid this without a more complex expression)
        // trim them and get rid of '.' (' .NET CLR' = 'net_clr') 
        prop.type = $.trim(prop.type).replace(".","").replace(" ","_"); 
        var value = prop.version ? prop.version : true;

        if (browser[prop.type]) {
            if (!$.isArray(browser[prop.type]))
                browser[prop.type] = new Array(browser[prop.type]);

            browser[prop.type].push(value);
        }    
        else browser[prop.type] = value;

        match = regex.exec(ua);
    }

    for (var i in browser)
        if (i.indexOf("mac") > -1)
            browser.mac = true;

    if (browser.windows_nt && !browser.windows)
        browser.windows = true;

    //put known browsers into the 'version' property for 'some' jquery compatibility

    //for sake of argument chromium 'is' chrome
    if (browser.chromium && !browser.chrome)
        browser.chrome = browser.chromium;

    //chrome / safari / webkit
    if (browser.chrome) {
        browser.version = browser.chrome;
    }
    else if (browser.safari) {
        browser.version = browser.safari;
    }
    else {
        if (browser.applewebkit)
            browser.webkit = browser.applewebkit;

        if (browser.webkit)
            browser.version = browser.webkit;
    }

    //firefox / gecko
    if (browser.firefox) {
        if (browser.rv)
            browser.version = browser.rv;

        else browser.version = browser.firefox;
    }
    else if (browser.gecko) {
        if (browser.rv)
            browser.version = browser.rv;

        else browser.version = browser.gecko;
    }

    //opera
    if (browser.opera && !browser.version)
        browser.version = browser.opera;

    //msie
    if (browser.trident && browser.rv) //ie11
        browser.msie = browser.rv;

    if (browser.msie)
        browser.version = browser.msie;

    $.browser = browser;//Rename to reduce confliction?

    //WAS USED FOR TESTING & DISCOVERY (very useful)
    //TODO: remove line below
    alert(JSON.stringify($.browser));

}) (jQuery);

В Internet Explorer 10 JSON.stringify выведет что-то вроде этого:

{"mozilla":"5.0","msie":"10.0","windows_nt":"6.2","trident":"6.0","net4.0e":true,"net4.0c":true,"net_clr":["3.5.30729","2.0.50727","3.0.30729"],"windows":true,"version":"10.0"}
person SilverX    schedule 23.10.2013

Короткий, но мощный.

// chrome, safari, webkit, mozilla, msie, opera
var chrome = /chrome/i.test(navigator.userAgent); 
person Victor    schedule 07.07.2014
comment
Можете ли вы объяснить синтаксис? Я не сталкивался с этой структурой? ТИА, /хром/ - person jchwebdev; 09.07.2014
comment
@jchwebdev уверен: var chrome [bool] /chrome/ [строка, которую мы ищем в UA] i [без учета регистра] test [метод] (navigator.userAgent) [возвращает строку UA для текущего браузера] Так что вы можете проверить это сафари,мозилла и т.д.. - person Victor; 10.07.2014

person    schedule
comment
Это круто. Очень тщательно и именно то, что мне было нужно. Я также собираюсь добавить несколько тестов версии, чтобы я мог ориентироваться на IE9. Спасибо за классный хак! - person Tabetha Moe; 06.07.2013