2009-06-25 13 views
15

Mi objetivo es poder llamar a las funciones que están dentro de mi plugin JQuery.Cómo llamar a funciones que están anidadas dentro de un complemento de JQuery?

¿Cuál es la sintaxis correcta?

Por ejemplo, esto no funciona:

<a href="#" id="click_me">Click Me</a> 

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script> 
<script> 
(function($) { 
    $.fn.foo = function(options) { 
     do_stuff = function(){ 
      console.log("hello world!"); // works 
      do_other_stuff = function(){ 
      alert("who are you?"); 
      } 
     } // function 
    } // function 
})(jQuery); 

$("body").foo(); 

$("#click_me").click(function(){ 
$.fn.foo.do_stuff.do_other_stuff(); // doesn't work 
}); 

</script> 

Respuesta

35

al asignar funciones a las variables sin la palabra clave var o bien sobrescribir la variable local de ese nombre o el se añaden al espacio de nombres global. (entonces tu do_stuff es una función global, que no es lo que quieres)

una forma de hacer lo que quieres es dar explícitamente donde quieres que resida tu función.

(function($) { 
    $.fn.foo = function(options) { 
     // whatever $().foo() should do 
    }; 

    $.fn.foo.do_stuff = function() { 
     console.log("hello world!"); 
    }; 

    $.fn.foo.do_stuff.do_other_stuff = function(){ 
     alert("who are you?"); 
    }; 
})(jQuery); 

Editar:

Esto funciona porque todas las funciones en JavaScript son objetos, lo que significa que puede asignar valores a cualquier propiedad arbitraria.

Si desea acceder a las variables de otras funciones que se pueden mover las definiciones dentro de los otros como:

$.fn.foo.do_stuff = function() { 
    console.log("hello world!"); 
    $.fn.foo.do_stuff.do_other_stuff = function(){ 
     alert("who are you?"); 
    }; 
}; 

pero esto va a significar la función sólo se define una vez que se ejecuta la otra función, y que cada vez que ejecutas la función sobrescribirá la última definición.

Posiblemente una solución más ideal sería tener cada función devuelve un objeto que contiene la función anidada como tan:

(function($) { 
    $.fn.foo = function(options) { 
     // whatever $().foo() should do 

     var do_stuff = function(do_stuff_args) { 
      console.log("hello world!"); 
      // do stuff with options and do_stuff_args 

      var do_other_stuff = function(other_args) { 
       alert("who are you?"); 
       // here you have access to options, do_stuff_args, and other_args 
      }; 

      return { 
       do_other_stuff: do_other_stuff 
      }; 
     }; 

     return { 
      do_stuff: do_stuff 
     } 
    }; 
})(jQuery); 

y lo llaman usando

foo().do_stuff(some_options).do_other_stuff(other_options); 

o

var a = foo(stuff).do_stuff(some_options); 
a.do_other_stuff(foo); 
a.do_other_stuff(bar); 
+0

Realmente no entiendo por qué funciona esto. Pensé que $ .fn.foo podría ser una función o un objeto con la propiedad do_stuff, pero en su ejemplo son ambos. Esto es posible en JavaScript? ¿Podría darme un puntero para leer sobre esta característica? ¿O me sale algo mal aquí? –

+0

Gracias por el ejemplo, funciona. Mi complemento ya está hecho. Tu ejemplo no coincide con la estructura de mi complemento. En mi complemento, "do_stuff" está dentro de "foo" y "do_other_stuff" está dentro de "do_stuff". ¿Cómo puedo acceder a "hacer otras cosas" usando esa estructura anidada? O bien, ¿cómo puedo usar su ejemplo, pero dejar do_stuff acceder a las variables de foo (y dejar do_other_stuff acceder a las variables de do_stuff)? – edt

+2

Gracias Cobbal, descubrí cómo usar tu ejemplo con la estructura de mi función. ¡Funciona genial! Solo tuve que usar $ .fn.foo. [Nombre_función] para todas las funciones anidadas, independientemente de su nivel. – edt

Cuestiones relacionadas