我在下面有以下代码,用于检查函数是否随时存在。 此代码目前没有任何错误。我正在使用这个,因为我的javascript文件以任意顺序加载,这对我的项目来说是必要的。由于我的javascript文件是分开的,以便在它们之间运行函数,你必须将它们存储在一个全局变量中,然后从全局变量中调用该函数。
Javascript文件示例:" checker.js" //这会检查函数是否存在!
var funcList = {};
$(document).ready(function(){
funcList.requireJS =
function requireJS(requires,callback){
console.log("requireJS Starting With Requires Below:");
console.log(requires);
var attempts = 0;
attemptRequire();
function attemptRequire(){
$.each(requires, function (key, value){
attempts++;
console.log("Checking:"+value+" attempts="+attempts);
if (typeof eval(value) !== 'undefined'){
callback(); //them run the function
}else{
console.log("require JS waiting...");
setTimeout(function(){attemptRequire();}, 100);//wait and try again every 100 milliseconds.
}
});
}
console.log("requireJS Finished!...");
};
});
使用全局函数的示例:sample.js
$(document).ready(function(){
console.log("Quote.Js Loading...");
requires = {
0 : "$.fn.mask"
};
funcList["requireJS"](requires, function(){
$("#partone_phone").mask("(999) 999-9999? x99999");
console.log("Quote.Js Loaded!");
});
});
这个想法是,如果用于屏蔽'在jQuery尚未加载,然后它不会尝试运行代码,但一旦加载它将。在未加载插件时尝试运行.mask将导致字段不具有所需的效果。我以jquery.mask为例,但这可以适用于任何事情。
我使用jquery.mask然而,因为作为一个jquery函数,似乎引用它的唯一方法是使用$ .fn.mask
通常情况下,我可以通过说 typeof functionNameHere !== 'undefined'
来测试函数,但是这样做有效,但是因为这是一个jquery函数,所以如果我发送字符串' $。fn.mask'它不起作用,除非我在它周围放一个eval()......我们都知道它是坏形式!
有没有人有更好的替代方法来使用eval()来完成这项工作?
另请注意:
requires = {
0 : $.fn.mask
};
尝试在没有字符串的情况下直接发送函数不起作用,因为如果它未定义,则在它到requireJS时它将保持未定义。
答案 0 :(得分:2)
更好的选择可能是传递要执行的函数,而不是返回您要查找的方法或错误。
requires = {
0 : function () {
return $ && $.fn && $.fn.mask;
}
};
现在,您只需致电requires[0]()
查看是否已定义$.fn.mask
。
附注:引用此作为" requireJS"可能会让未来的开发人员感到困惑,因为这不是requireJS,它只是你自己检查脚本是否完成加载的功能。 requireJS是一个模块加载器,如果你使用它可能会使这个问题不再是一个问题。
答案 1 :(得分:0)
答案 2 :(得分:0)
你能直接传递这个功能吗?
由于您eval
传递了名称,因此这些函数属于全局范围,您对它们所调用的上下文几乎没有兴趣。
不是传递名称并假设它们是可访问的,只需传递对该函数的引用并调用它。它将使您的设计更多更灵活。
requires = {
0 : $.fn.mask
};
和
if (value() !== 'undefined') {
callback(); //them run the function
如果您需要控制函数的执行上下文,请在传递函数之前使用bind
:
requires = {
0: $.fn.mask.bind($),
1: console.log.bind(console)
};
bind
method允许您准备具有给定范围和一些参数的函数。
答案 3 :(得分:0)
好的,最近我接受的答案产生了大量随机的javascript错误,这些错误会发生,并且不会向控制台报告错误。
我做了一个似乎更可靠的新算法,但依赖于eval()仍然......,但至少它有效。
我并不认为这是一个很好的答案,但它确实适用于我,也许它适用于其他人。
var funcList = {};
$(document).ready(function(){
//Because javascript files are loaded asynchronously, use requireJS to ensure javascript is loaded...
//...for your modules to prevent errors. To load this function from anyfile use the funcList global var.
//Helper function to get REAL type since mobile safari has issues
var toType = function(obj) {
return ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase()
}
funcList.requireJS =
function requireJS(requires,callback){
console.log("requireJS Starting With Requires Below****:");
console.log(requires);
var attempts = 0;
var successcount = 0;
attemptRequire();
function attemptRequire(){
successcount = 0;//reset it to 0
$.each(requires, function (key, value){
attempts++;
console.log("Checking*:"+value+" attempts="+attempts);
var type = '';
var errorOccured = false;
try{
console.log("trying...");
type = toType(eval(value));
console.log("type="+type);
if(type=="function"){
successcount++;
attempts--;
errorOccured = false;
}else{
console.log("throwing...");
throw "Custom error message: Function is undefined, must be defined as function";
}
}
catch (err){
errorOccured = true;
console.log("catching...");
console.log("error="+err.message);
}
finally {
if(errorOccured == true){
console.log("JS For "+value+" Not Ready Yet, Trying Again in 100ms");
setTimeout(function(){attemptRequire();}, 100);//wait and try again every 100 milliseconds.
return false;//exit the entire foreach loop early~
}
}
});
//Only call the callback once if all requires came in correctly.
if(successcount == Object.keys(requires).length){
console.log("calling callback...");
callback(); //then run the function
}
}
console.log("End of requireJS Function Call");
};
console.log("includes.js loaded");
});
如果您愿意,可以在此修改console.log,并且应该准备好了。在此处调用它是下面的示例。
$(document).ready(function(){
requires = {
0 : '$.fn.mask',
1 : '$.fn.validate',
2 : 'google.maps.LatLng'
};
funcList["requireJS"](requires, function(){
//code dependent upon mask and validate here!
});
});