2009-11-13 14 views
6

Supposons que j'ai ce ($ = jquery):

$.fn.my_function = function() { 
    function foo() 
    { 
     //do something 
    }; 

    function bar() 
    { 
     //do something other 
    }; 

} 

Je Lauch cela avec $('.my_class').my_function();

Maintenant, je dois appeler foo et bar sur le rappel à certains événements.

Comment puis-je les appeler?

Répondre

7

Vous devrez les exposer au «monde extérieur» en quelque sorte. Actuellement, ils ne sont visibles qu'à my_function, vous ne pourrez donc plus les appeler depuis n'importe où.

La façon la plus naïve de résoudre ce problème serait quelque chose comme:

var foo; 
var bar; 
$.fn.my_function = function() { 
    foo = function() { 
     //stuff 
    }; 
    bar = function() { 
     //stuff 
    }; 
}; 

Le même concept pourrait être appliqué à placer des références pour les partout qui fait sens pour votre utilisation.

+0

thx, simple et claire – apelliciari

2

HTML

<p id="hello">aaa</p> 
<p id="hola">sss</p> 
<div id='result'></div> 

JS

$.fn.my_function = function() 
{ 
    this.foo = function(xref) { 
     $("#result").append("<div>"+xref+".foo " + $(this).html() +"</div>"); 
    }; 

    this.bar = function(xref) { 
     $("#result").append("<div>"+xref+".bar " + $(this).html() +"</div>"); 
    }; 

    return this; 
}; 

var ee1 = $("#hello").my_function(); 
var ee2 = $("#hola").my_function(); 

ee1.bar("ee1"); 
ee2.bar("ee2"); 
$("#hello").html("hello hellboy"); 
ee1.foo("ee1"); 
ee2.foo("ee2"); 
$("#result").append("<hr />"); 
ee1.bar("ee1"); 
ee2.bar("ee2"); 
$("#hola").html("hola hellboy"); 
ee1.foo("ee1"); 
ee2.foo("ee2"); 
+0

bonne solution de rechange trop – apelliciari

7

Il semble que vous essayez de construire un plugin jQuery. Vous devez limiter les méthodes de votre plugin à un champ privé, et vous devez également itérer sur les éléments donnés au plug-in par le sélecteur jQuery, et les retourner en utilisant jQuery de « chacun » pour préserver les capacités enchaînant:

// wrap the plugin code inside an anonymous function 
// to keep the global namespace clean 
(function($){ 
    $.fn.my_function = function() { 
     return this.each(function(){ 
      function foo() { 
       // stuff here 
      } 
      function bar() { 
       // stuff here 
      } 
      // now you can use your foo and bar which ever way you want 
      // inside the plugin 
      $(this).focus(function(event){ 
       // do some stuff 
       ... 
       // call the function defined previously in the plugin code 
       foo(); 
      }); 
      $(this).blur(function(event){ 
       // do some stuff 
       ... 
       // call the function defined previously in the plugin code 
       bar(); 
      }); 
     }); 
    }; 
})(jQuery); 

vous voudrez peut-être jeter un oeil à ces articles pour plus d'informations sur le développement de plugin jQuery: http://www.learningjquery.com/2007/10/a-plugin-development-pattern

http://docs.jquery.com/Plugins/Authoring

Toutefois, si vous faites juste quelques « utilitaires » fonctions -type, vous pouvez simplement les attacher à Espace de noms jQuery comme ceci:

$.foo = function(){ 
     // do stuff 
    }; 
$.bar = function(){ 
     // do stuff 
    }; 
+0

oui vous avez le problème, presque .. je dois modifier un plugin, étendant sa méthode pour le monde +1 pour la très bonne explication ion :) – apelliciari

+0

@antti C'est un peu de ** goooood **. Et ce lien - à partir du site de requête - est génial .. Je l'ai déjà vu ..et étrangement - c'est l'un des morceaux de programmation les plus concis, les mieux formulés et les plus riches que j'ai lus ... par opposition au reste du site de jQuery qui "semble" comme il a été envisagé et exécuté par retarted les écoliers dans un trou d'enfer du tiers-monde. –

0

Une autre façon de gérer cette situation, ce qui est utile si vous voulez appeler votre méthodes de plug-ins d'ailleurs (peut-être un etc fichier différent) est d'écrire la logique de plug-in en tant que classe et puis instancier cette classe à l'intérieur le plugin jQuery, en stockant l'instance dans $.data.

(function($) { 

    var Animal = function(el, settings) { 
    this.$el = $(el); 
    this.settings = settings; 

    this.foo(); 
    }; 

    Animal.prototype.eat = function() { 
    // Do stuff 
    if (this.settings.isVegetarian) { 
     console.log('I eat plants'); 
    } else { 
     console.log('I eat meat'); 
    } 
    }; 

    Animal.prototype.play = function() { 
    // Do other stuff but return this.$el so you can maintain chain 
    return this.$el; 
    }; 

    // Create jQuery plugin 
    var pluginName = 'myPlugin'; 

    $.fn[pluginName] = function(options) { 
    // Defaults 
    var settings = $.extend({ 
     isVegetarian: true, 
    }, options); 

    return this.each(function() { 
     if (!$.data(this, pluginName)) { 
     // Store plugin instace with element (this), 
     // so public methods can be called later: 
     // $('.el').data('myPlugin').eat(); 
     $.data(this, pluginName, new Animal(this, settings)); 
     } 
    }); 
    }; 

}(jQuery)); 

Puis, quand vous voulez appeler votre plugin, il est comme normal:

$('.dog).myPlugin(); 

et appeler une méthode:

$('.dog').data('myPlugin').eat();