2012-01-26 18 views
19

Observo que se recomienda use named functions when binding an event handler to a javascript event. ¿Cómo puedo hacer esto cuando mi función necesita pasar el objeto this?

Por ejemplo, ¿cómo iba a reemplazar la función anónima a continuación llamando directamente doFancyStuff:

$(document).on('change', 'input.fancy-textbox', function() { 
    doFancyStuff($(this)); 
}); 

function doFancyStuff($textbox) { 
    // fanciness 
} 

puntos extra si usted señala otras convenciones que podría estar rompiendo con el código de seguridad.


Para aclarar, quiero llamar al método doFancyStuff() en mi ejemplo desde múltiples lugares, de lo contrario sí, yo podría hacer algo como esto:

$(document).on('change', 'input.fancy-textbox', doFancyStuff); 

function doFancyStuff() { 
    var $textbox = $(this); 

    // fanciness 
} 

Respuesta

10

Yo diría que es una cuestión de opinión. No veo ningún problema al usar una función anónima aquí. Si este es el único lugar doFancyStuff se llama, usted puede hacer esto:

$(document).on('change', 'input.fancy-textbox', doFancyStuff); 

function doFancyStuff() { 
    // fanciness 
    var $textbox = $(this) 
} 

Sin embargo, si esta función se llama desde múltiples lugares y no se puede cambiar la forma en que funciona, que tendría que hacer algo como esto:

$(document).on('change', 'input.fancy-textbox', doFancyStuffFromEvent); 

function doFancyStuffFromEvent() { 
    // fanciness 
    doFancyStuff($(this)); 
} 

function doFancyStuff($textbox) { 
    // fanciness 
} 

Which is messy.

+0

Lamentablemente, la función se llama desde varios lugares - algunos lugares donde 'this' no es el' $ textbox' Quiero que la función tener acceso a. ¿Tiene alguna sugerencia sobre cómo podría cambiar la función para que se adapte mejor a lo que necesito? – ajbeaven

+0

El segundo ejemplo es la forma de evitar esto, aunque prefiero el código que comenzó con la función anónima. Además, probablemente puedas usar el primero y verificar si el primer argumento es un objeto jquery o un evento y funcionan de manera diferente en cada uno, de nuevo me parece más desordenado que la función en línea. –

+0

Un ejemplo de la prueba del primer argumento para ver de qué tipo es: http://jsfiddle.net/Rzsep/ pero no lo estoy poniendo en mi respuesta porque no me gusta. Tenga en cuenta que la forma en que pruebo si es un evento es probablemente una forma horrible de probarlo, pero es rápido y sucio. –

7

sólo tiene que pasar a la función como es:

$(document).on('change', 'input.fancy-textbox', doFancyStuff); 

function doFancyStuff() { 
    $(this).fancy(); // :-P 
} 

jQuery invocará automáticamente su función con el contexto adecuado.


En cuanto a other conventions you might be breaking: ¿está seguro de que necesita delegación de eventos? Si no es así, esto sería mucho mejor:

$('input.fancy-textbox').on('change', doFancyStuff); 

o incluso se podría utilizar la versión corta a mano:

$('input.fancy-textbox').change(doFancyStuff); 
+0

Necesito delegación de evento en este caso, pero es un buen punto para otros que miran esta pregunta – ajbeaven

4

Que se va a poder utilizar $(this) dentro de su método doFancyStuff si usted lo define como su controlador de eventos. El método .on() establecerá el contexto (esto) en consecuencia:

$(document).on('change', 'input.fancy-textbox', doFancyStuff); 

function doFancyStuff() { 
    // 'this' will be the changed input.fancy-textbox 
} 
0

Tienes que cambiar doFancyStuff esperar que la misma firma que su función anónima. La forma en que ha codificado esto, parece que espera un único parámetro de un objeto jQuery e ignora "esto". Pero el parámetro de un evento es algo más (el objeto del evento) y "este" es el objetivo. Si desea utilizar una función como objetivo de evento, entonces debe esperar los mismos datos. Así que reescriba:

$(document).on('change', 'input.fancy-textbox', doFancyStuff); 

function doFancyStuff(e) { 
    var $textbox = $(this);  
    // fanciness 
} 
8

utilizo $.proxy para resolver este problema:

$(document).on('change', 'input.fancy-textbox', $.proxy(doFancyStuff, myChoiceofThis); 

function doFancyStuff(event) { 

    // $el is the same as $(this) when using anonymous functions 
    var $el = $(event.currentTarget); 

    // me === myChoiceOfThis 
    var me = this; // me === myChoiceOfThis 
} 

Si doFancyStuff es un método de objeto, a continuación, ser capaz de dar una referencia tal como myChoiceOfThis es muy útil.

+1

Esta es una forma muy ordenada de hacerlo. Puede ejecutar un controlador de eventos en el contexto de cualquier elemento que pase al proxy. 'var proxy = $ .proxy (doFancyStuff, $ ('.mi-otro-elemento'));' 'proxy();' –

+0

muy buena respuesta! mejor y más fácil manera de hacerlo! – Alphacoder

Cuestiones relacionadas