Как я могу эффективно использовать yepnope.js с $(document).ready()?

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

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

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

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

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

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

Ответы

Ответ 1

Если загрузка 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>

Ответ 2

Это техника, которую я использую. Это позволяет мне посыпать вызовы $(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() и выполняем их для реального.

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

Ответ 3

Теги

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

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

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

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

Ответ 4

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

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

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

Вот пример (только для иллюстративных целей используйте имена false libray/ script):

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 при завершении.

Ответ 5

Я думаю, что решение Alex Sexton было бы правильным:

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