По запросу Яш комментарий погрузчика


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

В Интернете я нашел библиотеки, которые обладают таким же функционалом, за исключением одного: они не проверяют уже нужны библиотеки существуют на странице.

Да, я мог бы выполнить необходимые библиотеки в локальной области видимости мой сценарий, но я решил уменьшить количество HTTP-соединений и трафика с этой функцией:

var require = function (lib, obj, libs_obj) {
    // if obj is function than `require` called directly by user and we
    // must transform it to object. It's for reduce number of used
    // variables. When we call `require` recursively, we use this object
    // instead of function
    var lib_is_list = typeof(lib) === 'object';
    if (typeof obj === 'function') obj = { callback: obj, count: lib_is_list ? lib.length : 1 }
    if (lib_is_list) { // this is list of libs
        for (var i in lib) require(lib[i], obj, libs_obj);
        return;
    }
    var lib = libs_obj[lib];
    if (lib.callbacks === undefined) lib.callbacks = [];
    if (lib.check()) { if (obj.callback) obj.callback(); return; }
    lib.callbacks.push(obj);
    if (lib.pending) { return; }
    lib.pending = true;

    function ready() {
        function script_downloaded() {
            lib.pending = false;
            var obj;
            while (obj = lib.callbacks.pop()) {
                obj.count--; if (obj.count == 0) obj.callback();
            }
        }

        download_script(lib.link, script_downloaded);
    }

    function download_script(src, callback) {
        var script = document.createElement('script');
        script.type = 'text/javascript';
        script.async = 'async';
        script.src = src;

        // Based on jQuery jsonp trick
        if (callback) {
            script.onload = script.onreadystatechange = function() {
                if (!script.readyState || /loaded|complete/.test(script.readyState)) {
                    script.onload = script.onreadystatechange = null;
                    callback();
                }
            };
        }
        document.getElementsByTagName('head')[0].appendChild(script);
    }

    var deps_count = lib.deps ? lib.deps.length : 0;
    if (deps_count < 1) { ready(); return; }
    var new_obj = { callback: ready, count: deps_count };

    require(lib.deps, new_obj, libs_obj);
};

Эта функция работает в IE6+ (и, конечно, в других браузерах) и написан на чистом JavaScript. Для вызова этой функции используйте следующий синтаксис:

require(['list', 'of', 'libraries'], function () { alert 'All libs loaded'; }, libs_obj),

где libs_obj это объект такой:

{
    list: {
        check: function() { return list_exist(); },
        // function to check whether the required functionality
        link: 'js/list_js_file.js',
        // link to script
        deps: ['libraries', 'of']
        // list of dependencies of current library
        // If not, library doesn't have dependencies
    },
    of: {
        check: function() { return of_exist_and_version_is('1.2.3'); },
        link: 'js/another_file.js',
    },
    libraries: {
        check: funcion() { return libraries_exist() || analog_exist(); },
        link: 'http://www.example.com/js/libraries.js',
        deps: ['of']
    }
}

Функции обратного вызова являются необязательными, если нам не нужно, мы можете просто ввести ложные или неопределенные. Конечно, эта функция должна вызываться после того, как все сторонние скрипты. Внизу страницы есть лучшее место для скрипта с этой функцией. Пожалуйста, скажите мне, где я пошло не так или дать мне полезный совет.



337
4
задан 9 мая 2011 в 07:05 Источник Поделиться
Комментарии
1 ответ

Мои 2 цента:


  • пожалуйста, используйте строчные верблюжьего ( lib_is_list -> libIsList )

  • Первые 5 строк кажутся неуклюжими

    • Проверка на массив с объектом вызова typeof '' странно

    • Изменение типа параметра переменной/нечетное и не рекомендуется делать это дважды

    • Не падение строк ( для (ВАР я в lib) требуют(Либ[я], obj, а libs_obj); )


  • Вы можете использовать Либ.обратные вызовы = Либ.обратные вызовы || [] вместо Если (Либ.обратные вызовы === неопределено) Либ.обратные вызовы = [];

  • Зачем назначать сначала обратных, а потом проверить (), должны ли вы вернуться

  • Ваше обращение к obj , рассчитывать и обратные вызовы - это Пятерочка, отсутствие строк не помочь,

  • Имя функции готов() жаль, готово наиболее commly используется для обратного вызова после того, как HTTP-запросов

  • Вы должны рассмотреть вопрос о слиянии/переработку готовых/script_downloaded/download_script

  • Параметр src, к сожалению, поскольку он не содержит источника, может быть URL-адрес ?

  • Мне нравится защитного программирования, но проверка обратного вызова , кажется, много, так как ваш код гарантирует это

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

2
ответ дан 16 декабря 2013 в 10:12 Источник Поделиться