Автоматическая загрузка / включение для JavaScript - PullRequest
3 голосов
/ 10 октября 2011

У меня есть файл с именем common.js, и он включается в каждую страницу моего сайта с использованием <script />.

. Он будет быстро расти по мере роста функциональности моих сайтов (надеюсь, я представляю).:)

Давайте рассмотрим у меня событие jQuery:

$('#that').click(function() {

    one_of_many_functions($(this));

}

На данный момент у меня есть one_of_many_functions() в common.js.

Возможно ли это как-то возможно?что JavaScript автоматически загружает файл one_of_many_functions.js при вызове такой функции, но ее не существует?Нравится автозагрузчик.:)

Второй вариант, который я вижу, состоит в том, чтобы сделать что-то вроде:

$('#that').click(function() {

    include('one_of_many_functions');

    one_of_many_functions($(this));

}

Это не так автоматически, но все же - включает в себя требуемый файл.

Это что-то из этоговозможный?Спасибо за совет!:)

Ответы [ 3 ]

4 голосов
/ 10 октября 2011

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

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

Вам потребуется настроить центральный объект, который отслеживает, какие активы уже загружены. Вот быстрый макет этого:

var assets = {
    assets: {},
    include: function (asset_name, callback) {
        if (typeof callback != 'function')
            callback = function () { return false; };

        if (typeof this.assets[asset_name] != 'undefined' )
            return callback();


        var html_doc = document.getElementsByTagName('head')[0];
        var st = document.createElement('script');
        st.setAttribute('language', 'javascript');
        st.setAttribute('type', 'text/javascript');
        st.setAttribute('src', asset_name);
        st.onload = function () { assets._script_loaded(asset_name, callback); };
        html_doc.appendChild(st);
    },
    _script_loaded: function (asset_name, callback) {
        this.assets[asset_name] = true;
        callback();
    }
};

assets.inlude('myfile.js', function () {
    /* do stuff that depends on myfile.js */
});
0 голосов
/ 02 июля 2014

Я создал нечто похожее на это год назад. На самом деле, я нашел эту тему путем поиска, если это что-то новое в этой области. Вы можете увидеть, что я создал здесь: https://github.com/thiagomata/CanvasBox/blob/master/src/main/New.js

Мой проект, почти 100% ООП. Итак, я использовал этот факт, чтобы сфокусировать свое решение. Я создаю этот «Класс» с именем «Новый», к которому привыкли, сначала загружаю, а потом копирую объекты.

Вот пример того, кто его использует:

 var objSquare = New.Square(); // Square is loaded and after that instance is created
     objSquare.x = objBox.width / 2;
     objSquare.y = objBox.height / 2;

 var objSomeExample = New.Stuff("some parameters can be sent too");

В этой версии я не использую некоторые json со всеми позициями файла js. Отображение является хардкорным, как вы можете видеть здесь:

New.prototype.arrMap = {
    CanvasBox: "" + window.MAIN_PATH + "CanvasBox",
    CanvasBoxBehavior: "" + window.MAIN_PATH + "CanvasBoxBehavior",
    CanvasBoxButton: "" + window.MAIN_PATH + "CanvasBoxButton",
    // (...)
};

Но сделайте это более автоматическим, я думаю, что использовать gulp или grunt - это не так сложно.

Это решение было создано для использования в проекте. Таким образом, коду могут потребоваться некоторые изменения, чтобы его можно было использовать в любом проекте. Но может быть началом.

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


Как я уже говорил, это все еще рабочий прогресс. Но я создал более независимый модуль, который использует gulp для его обновления.

Все магические очереди можно найти в этих ссылках: https://github.com/thiagomata/CanvasBox/blob/master/src/coffee/main/Instance.coffee
https://github.com/thiagomata/CanvasBox/blob/master/src/node/scripts.js https://github.com/thiagomata/CanvasBox/blob/master/gulpfile.js

Особый взгляд должен быть в этих строках Instance.coffee

###
# Create an instance of the object passing the argument
###
instaceObject = (->
  ClassElement = (args) ->
    window[args["0"]].apply this, args["1"]
  ->
    ClassElement:: = (window[arguments["0"]])::
    objElement = new ClassElement(arguments)
    return objElement
)()

Эта строка позволяет мне инициализировать экземпляр некоторого объекта после загрузки его файла. Как используется в методе создания:

create:()->
  @load()
  return instaceObject(@packageName, arguments)
0 голосов
/ 10 октября 2011

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

A) Вы несете дополнительную ответственность за поддержание вашего индексного объекта / механизма поиска, чтобы ваши сценарии знали, где искать, когда вызываемая функция не может быть найдена.

B) Это еще одна вещь, которая может пойти не так при отладке вашего растущего проекта.

Я уверен, что кто-то еще упомянет об этом ко времени, когда я закончу писать, но, возможно, вам лучше потратить время на выяснение, как объединить весь ваш код в один файл .js. Преимущества для этого: хорошо документировано .

...