2010-05-27 8 views
2

J'utilise une fonction de charge paresseux le moteur de sélecteur Sizzle (utilisé par jQuery):Comment transmettre un nombre variable de paramètres avec une fonction de rappel?

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

} 

je définir les onload et onreadystatechange gestionnaires d'événements, ainsi que le drapeau sizzle_loaded d'appeler une autre fonction (gather_content()) dès que Sizzle est chargé. Tout cela est nécessaire pour faire cela de manière croisée.

Jusqu'à présent, mon projet ne devait charger que Sizzle à un moment donné dans le script, donc j'ai pu coder en dur l'appel de fonction gather_content() dans la fonction load_sizzle().

Cependant, j'ai maintenant besoin de charger Sizzle à deux endroits différents dans le script, et d'appeler une fonction différente chaque fois qu'une fois chargé. Mon premier instinct était de modifier la fonction d'accepter une fonction de rappel:

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

} 

Ensuite, je pouvais l'appeler comme ceci:

load_sizzle(module_name, gather_content); 

Cependant, l'autre fonction de rappel que je dois utiliser prend plus de paramètres que gather_content() fait.

Comment puis-je modifier ma fonction afin de pouvoir spécifier un nombre variable de paramètres à transmettre avec la fonction de rappel? Ou, est-ce que je vais à ce sujet dans le mauvais sens?

Finalement, je veux juste charger Sizzle, puis appeler toute fonction dont j'ai besoin (avec les arguments dont il a besoin) une fois le chargement terminé.

Merci pour toute aide!

Répondre

3

L'idée générale ici est de créer une fermeture ou lambda. D'une certaine manière, vous pouvez les considérer comme une fonction préchargée avec des paramètres prêts à être appelés. Ceci est également parfois appelé un délégué.

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

Alors, pour votre autre cas

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

Plus sur la lecture closures.

+0

Génial, merci, Peter! – Bungle

2

Vous pouvez utiliser la méthode sur le appliquer rappel:

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

} 

Puis, comme troisième argument de load_sizzle vous pouvez passer un tableau d'arguments supplémentaires pour la fonction.

Vous pouvez également améliorer le code avec ceci:

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

} 

De cette façon, le nombre d'arguments 4 (si spécifié) peut être un objet qui sera le « ce » dans le rappel que vous passez.

+0

Merci beaucoup, mck89!J'ai fini par utiliser la solution de Peter Bailey (elle me semble plus élégante et nécessite moins de changements de code). Cependant, FWIW, votre réponse était très instructive en soi. Merci encore! – Bungle

2

Vous pouvez utiliser le tableau arguments pour obtenir tous les arguments transmis à la fonction.

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

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