2010-05-27 90 views
2

我使用一个函数来延迟加载的Sizzle选择器引擎(的jQuery使用):如何传递可变数量的参数以及回调函数?

var sizzle_loaded; 

// load the Sizzle script 
function load_sizzle(module_name) { 

    var script; 

    // load Sizzle script and set up 'onload' and 'onreadystatechange' event 
    // handlers to ensure that external script is loaded before dependent 
    // code is executed 
    script = document.createElement('script'); 
    script.src = 'sizzle.min.js'; 
    script.onload = function() { 
    sizzle_loaded = true; 
    gather_content(module_name); 
    }; 
    script.onreadystatechange = function() { 
    if ((script.readyState === 'loaded' || script.readyState === 'complete') && 
     !sizzle_loaded) { 
     sizzle_loaded = true; 
     gather_content(module_name); 
    } 
    }; 

    // append script to the document 
    document.getElementsByTagName('head')[0].appendChild(script); 

} 

我设置onloadonreadystatechange事件处理程序,以及在sizzle_loaded标志调用另一个函数(gather_content() )一旦Sizzle加载完成。所有这些都需要以跨浏览器的方式来完成。

到目前为止,我的项目只需要在脚本中一次性延迟加载Sizzle,所以我能够将gather_content()函数调用硬编码到load_sizzle()函数中。

但是,我现在需要在脚本中的两个不同点上延迟加载Sizzle,并且一旦加载它即可调用不同的函数。我的第一反应是修改函数接受一个回调函数:

var sizzle_loaded; 

// load the Sizzle script 
function load_sizzle(module_name, callback) { 

    var script; 

    // load Sizzle script and set up 'onload' and 'onreadystatechange' event 
    // handlers to ensure that external script is loaded before dependent 
    // code is executed 
    script = document.createElement('script'); 
    script.src = 'sizzle.min.js'; 
    script.onload = function() { 
    sizzle_loaded = true; 
    callback(module_name); 
    }; 
    script.onreadystatechange = function() { 
    if ((script.readyState === 'loaded' || script.readyState === 'complete') && 
     !sizzle_loaded) { 
     sizzle_loaded = true; 
     callback(module_name); 
    } 
    }; 

    // append script to the document 
    document.getElementsByTagName('head')[0].appendChild(script); 

} 

然后,我可以这样称呼它:

load_sizzle(module_name, gather_content); 

但是,我需要使用其他的回调函数比gather_content()更多的参数。

我该如何修改我的函数,以便可以指定可变数量的参数,并使用回调函数进行传递?或者,我是否以这种错误的方式去做?

最终,我只是想加载Sizzle,然后在完成加载后调用我需要的任何函数(以及它需要的任何参数)。

感谢您的帮助!

回答

3

这里的一般想法是创建一个闭包或lambda。在某种程度上,您可以将它们视为一个预先载入参数的函数,这些参数已准备好被调用。这也有时称为代表。

load_sizzle(module_name, function() 
{ 
    gather_content(); 
}); 

然后,您的其他情况

load_sizzle(module_name, function() 
{ 
    some_other_function(param1, param2); 
}); 

更多阅读上closures

+0

太棒了,谢谢彼得! – Bungle 2010-05-27 16:53:13

2

您可以在回调使用申请方法:

function load_sizzle(module_name, callback,args) { 

    var script, args=args || []; //Be sure that an array is passed 

    // load Sizzle script and set up 'onload' and 'onreadystatechange' event 
    // handlers to ensure that external script is loaded before dependent 
    // code is executed 
    script = document.createElement('script'); 
    script.src = 'sizzle.min.js'; 
    script.onload = function() { 
    sizzle_loaded = true; 
    callback.apply(window,[module_name].concat(args)); //Add the module_name as first argument and then every other argument specified by the user 
    }; 
    script.onreadystatechange = function() { 
    if ((script.readyState === 'loaded' || script.readyState === 'complete') && 
     !sizzle_loaded) { 
     sizzle_loaded = true; 
     callback(module_name); 
    } 
    }; 

    // append script to the document 
    document.getElementsByTagName('head')[0].appendChild(script); 

} 

然后作为load_sizzle的第三个参数,你可以通过额外的参数数组的功能。

还可以改善与此代码:

function load_sizzle(module_name, callback,args,bind) { 

    var script, args=args || [],bind=bind || window; 

    // load Sizzle script and set up 'onload' and 'onreadystatechange' event 
    // handlers to ensure that external script is loaded before dependent 
    // code is executed 
    script = document.createElement('script'); 
    script.src = 'sizzle.min.js'; 
    script.onload = function() { 
    sizzle_loaded = true; 
    callback.apply(bind,[module_name].concat(args)); //Add the module_name as first argument and then every other argument specified by the user 
    }; 
    script.onreadystatechange = function() { 
    if ((script.readyState === 'loaded' || script.readyState === 'complete') && 
     !sizzle_loaded) { 
     sizzle_loaded = true; 
     callback(module_name); 
    } 
    }; 

    // append script to the document 
    document.getElementsByTagName('head')[0].appendChild(script); 

} 

这样的说法号4(如果指定)可以是一个对象,这将是“本”与您传递的回调中。

+0

非常感谢mck89!我最终选择了Peter Bailey的解决方案(这对我来说似乎更优雅,并且需要更少的代码更改)。然而,FWIW,你的答案本身就是非常有教育意义的。再次感谢! – Bungle 2010-05-27 16:55:26

2

您可以使用arguments数组来获取传递给函数的所有参数。

function example() { 
for(var i = 0; i < arguments.length; i++) { 
    alert('argument ' + i + ' ' + arguments[i]); 
} 
} 

example('any', 'number', 'of', 'arguments);