Программно включать JQuery в среде с высокими конфликтами -

StackOverflow https://stackoverflow.com/questions/1005600

Вопрос

Я пишу фрагмент кода для размещения на любом стороннем веб-сайте и не знаю, в какую среду он будет добавлен. Моя конечная цель - чтобы значок был

<script src="http://example.com/js/badge.js"></script>

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

Это лучшее, что я мог придумать. Я не хочу, чтобы что-либо до или после моего скрипта подвергалось воздействию каких-либо оставшихся переменных или странных коллизий. Кто-нибудь видит какие-либо проблемы?

(function() {
    function main($) {
        // do stuff with $
        $(document.body).css("background", "black")
    }

    // If jQuery exists, save it
    var old_jQuery = null;
    if (typeof(jQuery) != "undefined") {
        if (typeof(jQuery.noConflict) == "function") {
            old_jQuery = jQuery.noConflict(true);
        }
    }

    var addLibs = function() {
        // Body isn't loaded yet
        if (typeof(document.body) == "undefined" || document.body === null) {
            setTimeout(addLibs, 100);
            return;
        }

        var node = document.createElement("script");
        node.src = "http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js";
        document.body.appendChild(node);
        checkLibs();
    }

    var checkLibs = function() {
        // Library isn't done loading
        if (typeof(jQuery) == "undefined" || jQuery("*") === null) {
            setTimeout(checkLibs, 100);
            return;
        }
        var new_jQuery = jQuery.noConflict(true);
        jQuery = old_jQuery;
        main(new_jQuery);
    }

    addLibs();
})();
Это было полезно?

Решение

Я закончил с http://yourock.paulisageek.com/js/popup.js См. Тест (с доступной регистрацией консоли) http://paulisageek.com/tmp/jquery-programatics. HTML . Он не сбрасывает jQuery и $ до тех пор, пока jQuery фактически не завершит загрузку. Любой способ заблокировать JavaScript без бесконечного цикла (который блокирует саму загрузку jQuery)?

// A namespace for all the internal code
var yourock = {};

// Include JQuery programatically
(function() {
    // Don't let the script run forever
    var attempts = 30;

    // If jQuery exists, save it and delete it to know when mine is loaded
    var old_jQuery;
    if (typeof(jQuery) != "undefined") {
        if (typeof(jQuery.noConflict) == "function") {
            old_jQuery = jQuery;
            delete jQuery;
        }
    }

    var addLibs = function() {
        var head = document.getElementsByTagName("head");
        if (head.length == 0) {
            if (attempts-- > 0) setTimeout(addLibs, 100);
            return;
        }

        var node = document.createElement("script");
        node.src = "http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js";
        head[0].appendChild(node);
        checkLibs();
    }

    var checkLibs = function() {
        // Library isn't done loading
        if (typeof(jQuery) == "undefined" || typeof(jQuery) != "function" || jQuery("*") === null) {
            if (attempts-- > 0) setTimeout(checkLibs, 100);
            return;
        }
        yourock.jQuery = jQuery.noConflict(true);
        if (typeof old_jQuery == "undefined")
            jQuery = old_jQuery;
    }

    addLibs();
})();

Другие советы

Это работает:

(function(){
    if (window.jQuery !== undefined) {
        doStuff(jQuery);
    } else {
        var script = document.createElement('script');
        script.src = 'http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js';
        document.getElementsByTagName('head')[0].appendChild(script);
        var interval = setInterval(function(){
            if (window.jQuery) {
                clearInterval(interval);
                var JQ = jQuery.noConflict(true);
                doStuff(JQ);
            }
        }, 100);
    }
})();

function doStuff($) { /* Do stuff with $ */ }

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

Я не так много тестировал этот код, но он должен работать ...

(function($, window) {
    var version = ($ && typeof($) == 'function' && $().jquery ? ($().jquery).split('.').join('') : 0), // 1.8.1 -> 181
        jBack   = null;
    if (version) console.log('jQuery current version : ', version);
    else         console.log('no jQuery');
    var loaded = function() {
            console.log('loaded()');
            var $ = jQuery.noConflict(true); // LOCAL own jQuery version
            if (jBack)  {
                window.$      = jBack; // Reassign ex-jQuery
                window.jQuery = jBack;
            }
            // OK : now work with OUR new $
            console.log('jQuery new version : ', $().jquery);
        },
        loadJs = function(jsPath) {
            console.log('loadJs()');
            var s = document.createElement('script');
            s.setAttribute('type', 'text/javascript');
            s.setAttribute('src', jsPath);
            s.onload = loaded;
            document.getElementsByTagName('body')[0].appendChild(s);
        };

    if (version) jBack = $;
    if (version < 180) loadJs('http://code.jquery.com/jquery-1.9.1.min.js');
    else loaded();

})((typeof(jQuery) == 'function' ? jQuery : null), window);
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top