我有一个名为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));
}
不是那么自动,但仍然 - 包括想要的文件。
这有可能吗?谢谢你的建议! :)
答案 0 :(得分:4)
无法根据需要直接自动加载外部javascripts。但是,可以实现类似于您提到的第二条路线的动态包含机制。
但是有一些挑战。当您“包含”新的外部脚本时,您将无法立即使用所包含的功能,您必须等到脚本加载。这意味着您将不得不在某种程度上对代码进行分段,这意味着您必须做出一些决定,这些决定应该包含在核心中的内容与可以根据需要包含的内容。
您需要设置一个中心对象,以跟踪已加载的资产。这是一个快速的模型:
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 */
});
答案 1 :(得分:0)
当然有可能 - 但这可能会让管理变得痛苦。为了实现这样的东西,你将不得不维护一个函数索引及其相应的源文件。随着你的项目的发展,这可能会因为一些原因而变得麻烦 - 我脑子里突出的是:
A)您还有责任维护索引对象/查找机制,以便您的脚本知道无法找到您正在调用的函数时的位置。
B)在调试不断增长的项目时,还有一件事可能会出错。
我确信在我写完这篇文章的时候,其他人会提到这个,但是你的时间可能会花更多时间来弄清楚如何将所有代码合并到一个.js文件中。这样做的好处是well-documented。
答案 2 :(得分:0)
我创造了与一年前相近的东西。事实上,我通过搜索找到了这个线程,如果这是该领域的新事物。您可以在此处查看我创建的内容:https://github.com/thiagomata/CanvasBox/blob/master/src/main/New.js
我的项目几乎是100%的OOP。所以,我用这个事实来集中我的解决方案。我创造了这个&#34; Class&#34;名为&#34; New&#34;什么是习惯,首先加载和实例后的对象。
以下是使用它的人的一个例子:
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方法中使用的那样:
create:()->
@load()
return instaceObject(@packageName, arguments)