2

我有一个文件被调用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));

}

这不是那么自动,但仍然 - 包括想要的文件。

这有可能吗?感谢您的建议!:)

4

3 回答 3

3

无法按需直接自动加载外部 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 */
});
于 2011-10-10T17:23:25.503 回答
0

当然这是可能的——但这可能会变得难以管理。为了实现这样的东西,您将不得不维护函数的索引及其相应的源文件。随着您的项目的发展,这可能会因为几个原因而变得麻烦——我脑海中最突出的两个原因是:

A)您有额外的责任维护您的索引对象/查找机制,以便您的脚本知道在找不到您调用的函数时在哪里查找。

B)这是调试您不断增长的项目时可能出错的另一件事。

我敢肯定,当我写完这篇文章时,其他人会提到这一点,但是您最好花时间弄清楚如何将所有代码合并到一个 .js 文件中。这样做的好处是有据可查的

于 2011-10-10T17:24:09.300 回答
0

一年前,我创造了一些接近于此的东西。事实上,如果这是该领域的新事物,我已经通过搜索找到了这个线程。您可以在这里看到我创建的内容:https ://github.com/thiagomata/CanvasBox/blob/master/src/main/New.js

我的项目几乎是 100% OOP。所以,我用这个事实来集中我的解决方案。我使用名称“New”创建这个“类”,首先加载对象,然后再实例化对象。

这是某人使用它的示例:

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

在这个版本中,我没有使用一些带有所有 js 文件位置的 json。正如您在此处看到的那样,映射是核心:

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 方法中使用:

create:()->
  @load()
  return instaceObject(@packageName, arguments)
于 2014-07-02T16:01:52.577 回答