2009-11-13 7 views
6

Supongamos que tengo esto ($ = jQuery):

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

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

} 

I LAUCH esto con $('.my_class').my_function();

Ahora, tengo que llamar a foo y bar en devolución de llamada para ciertos eventos.

¿Cómo puedo llamarlos?

Respuesta

7

Tendrás que exponerlos al "mundo exterior" de alguna manera. Actualmente, solo están visibles en my_function, por lo que no podrá llamarlos desde ningún otro lado.

La forma más ingenua de solucionar este problema sería algo así como:

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

El mismo concepto se podría aplicar a colocar referencias a ellos en cualquier lugar que tenga sentido para su uso.

+0

THX, sencilla y buena solución clara – 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

alternativa demasiado – apelliciari

7

Parece que usted está tratando de construir un plugin de jQuery. Usted debe limitar los métodos de su plugin para un ámbito privado, y también se debe iterar sobre los elementos dados al complemento por el selector de jQuery, y devolverlos mediante el uso de jQuery de "cada uno" para preservar las habilidades en cadena:

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

Es posible que desee echar un vistazo a estos artículos para obtener más información sobre el desarrollo de plugin de jQuery: http://www.learningjquery.com/2007/10/a-plugin-development-pattern

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

Sin embargo, si usted está haciendo sólo algunos "servicios públicos" funciones de tipo, que sólo les puede atar a Espacio de nombres jQuery como este:

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

sí, usted tiene el problema, casi .. tengo que modificar un complemento, extendiendo su método para el mundo +1 para la muy buena explicación ion :) – apelliciari

+0

@antti Eso es algo ** goooood ** repetitivo. Y ese enlace, del sitio de consulta, es genial ... Lo he visto antes ...y, curiosamente, es una de las piezas de "visión" de programación más concisas, bien redactadas y ricas que he leído en mi vida ... a diferencia del resto del sitio de jQuery que "parece" como si hubiera sido visualizado y ejecutado por reutilización escolares en algún hoyo infernal del tercer mundo. –

0

Otra manera de manejar esta situación, que es útil si desea llamar a los métodos de su plugin desde otro lugar (tal vez un archivo, etc. diferente) es escribir la lógica de complemento como una clase y luego una instancia de esa clase en el interior el complemento jQuery, que almacena la instancia en $.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)); 

Entonces, cuando usted quiere llamar a su complemento, es sólo como normal:

$('.dog).myPlugin(); 

y llamar a un método:

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