Как эффективно использовать yepnope.js с $ (document) .ready ()? - PullRequest
15 голосов
/ 14 апреля 2011

Я реализовывал загрузчик скриптов yepnope как часть библиотеки modernizr.js. Я успешно получил jQuery для загрузки и jQuery-зависимые сценарии впоследствии. Я новичок в асинхронной загрузке ресурсов, так что это немного ново для меня. Я искал вокруг, но мне не очень повезло со следующим.

Мой вопрос: что вы думаете о том, как эффективно заменить функциональность $ (document) .ready () при работе с фреймворком yepnope.js?

Моя теория состояла в том, чтобы создать функцию с соответствующим именем в моей базовой библиотеке, а затем установить эту переменную на моих страницах в анонимную функцию, содержащую мой существующий код $ (document) .ready (). Затем эта переменная будет вызываться yepnope после того, как все сценарии были загружены в полный обратный вызов.

Согласитесь ли вы с тем, что это хороший способ сделать это, или я подхожу к этому совершенно неправильно?

(Для тех, кто не знает, асинхронный характер yepnope.js означает, что документ вызывает $ или jQuery до того, как загрузчик yepnope завершил работу, выдавая ошибку "$ is undefined"

Первый вопрос, надеюсь, он хороший.

Ответы [ 5 ]

11 голосов
/ 06 марта 2012

Если загрузка jQuery без yepnope не является для вас проблемой, есть более простой способ сделать это.

<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>

<script>
    $.holdReady(true);

    yepnope.load({
        load: [
            'placeholder.js',
            'jquery-ui.min.js'
        ],
        complete: function (){
            $.holdReady(false);
        }
    });
</script>
11 голосов
/ 20 декабря 2011

Это техника, которую я использую. Это позволяет мне посылать вызовы в стиле $ (document) .ready () куда угодно. Используя этот метод, вы можете взять сайт, который уже использует jQuery и имеет существующие вызовы $ (document) .ready (), и легко модифицировать yepnope.

Сначала добавьте эту строку JS, желательно в заголовок документа, перед любым JavaScript, который вызывает $ (document) .ready ():

<script>
    var docready=[],$=function(o){function r(fn){docready.push(fn);}if(typeof o === 'function') r(o);return{ready: r}};
</script>

Затем установите тестовый объект yepnope jQuery, подобный следующему:

yepnope({
    load: '//ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js',
    complete: function() {
        $ = jQuery;         
        for(n in docready) $(document).ready(docready[n]);
    }
});

Мы создаем поддельный $ (document) .ready () перед загрузкой jQuery. Это сохраняет каждый вызов $ (document) .ready () в массиве docready. Затем, после загрузки jQuery, мы перезаписываем наш временный объект $ теперь загруженным реальным объектом jQuery. Затем мы выполняем все сохраненные вызовы $ (document) .ready () и выполняем их по-настоящему.

ОБНОВЛЕНО: улучшенная версия от Криса Джонса, которая также охватывает вызовы стиля $ (function () {}).

1 голос
/ 17 апреля 2011

теги скрипта загружаются синхронно - поэтому, если вы поместите свой yepnope в файл js и загрузите его с помощью тега скрипта:

   <script type="text/javascript" src="/my-yepnope-stuff.js"></script>
</body>

прямо перед закрывающим тегом body, вы можете быть совершенно уверены, что он равен $(document) .ready ().

Что вам нужно для себя ответить, так это то, имеет ли смысл принудительно загружать yepnope способом $ (document) .ready (), поскольку его основная цель -в первую очередь нарушить порядок синхронной загрузки тегов скрипта.

0 голосов
/ 26 июля 2013

Я думаю, что Алекс Секстон решение будет правильным:

yepnope({
    load: '//ajax.googleapisOFFLINE.com/ajaxX/libs/jquery/1.7.1/jquery.min.js',
    callback: function () {
        if (!window.jQuery) {
            yepnope('/js/jquery-1.7.1.min.js');
        }
    },
    complete: function () {
      $(function(){
        $("div.whatever").css("color","red");
      });
    }
});
0 голосов
/ 13 мая 2011

Используя руководство @ezmilhouse, я подумал о том, как лучше всего достичь того, чего я достиг, при этом сохраняя совместимость с нашим старым кодом.

Мое решение состояло в том, чтобы настроить загрузчик сценариев yepnope для загрузки всех необходимых сценариев в иерархическом порядке, исходя из их индивидуальных зависимостей. После загрузки всех сценариев вы можете использовать свойство complete моего вызова yepnope для вызова моей функции готовности. Это означало, что документ был фактически готов и код работал бы без проблем.

Я также перенес свои js в базу своих страниц (что я должен был сделать давным-давно, но у нас было много старых страниц! :))

Вот пример (использование ложных имен библиотек / скриптов только для иллюстрации):

yepnope({
    test: baseLib.debug,
    yep: { "max": "/version2/res/jquery/jquery-1.5.2.js" },
    nope: { "min": "/version2/res/jquery/jquery-1.5.2.min.js" },
    callback: {
        "max": function (url, result, key) {
            baseLib.Log("jQuery full loaded.");
        },
        "min": function (url, result, key) {
            baseLib.Log("jQuery min loaded.");
        }
    },
    complete: function () {
        if (window.$) {
            yepnope({
                test: base.debug,
                yep: {
                   "anotherscript": "script/url/here.js",
                   "anotherscript2": "script/url/here2.js"
                },
                nope: {
                    "anotherscript": "script/url/here-min.js",
                    "anotherscript2": "script/url/here2-min.js"
                },
                both: {
                    "anotherscript3": "script/url/here3.js"
                },
                callback: {
                    "anotherscript": function (url, result, key) {
                        baseLib.Log("anotherscript " + (result ? "Max" : "Min") + " loaded.");

                    },
                    "anotherscript2": function (url, result, key) {
                        baseLib.Log("anotherscript2 " + (result ? "Max" : "Min") + " loaded.");
                    },
                    "anotherscript3": function (url, result, key) {
                        baseLib.Log("anotherscript3 loaded.");
                    }
                },
                complete: function () {
                    baseLib.Log("Scripts Loaded");
                    baseLib.Page.Ready();
                }
            });

        }
        else {
            baseLib.Log("Could not load jQuery. No further jQuery dependent files loaded.", "error");
        }
    }
});

На моей странице js я назначу функцию для baseLib.Page.Ready, которая затем будет вызвана yepnope при завершении.

...