2011-06-20 21 views
5

Estoy escribiendo un plugin de jQuery, pero estoy teniendo un problema:evento Click no funciona correctamente en el plugin de jQuery

Mi elemento HTML

<a id="trac"></a> 

Mi JS que llama el plugin

$('#trac').myplugin(); 

Mi complemento

$.fn.myplugin = function(){ 
    var $root; 
    return this.each(function(){ 
     $root = $(this); 
     $root.live('click',function(){ 
      console.log('here'); 
     }); 
    }); 
} 

Sucede que "aquí" nunca se muestra. Pero si uso ...

$('#trac').live('click',function(){ 
    console.log('here'); 
}); 

... "aquí" en la pantalla. No entiendo por qué está sucediendo porque $ root y $ ('# trac') son exactamente el mismo objeto jQuery.

¿Cómo puedo repararlo?

Gracias!

+1

Está su plugin de carga antes se llama y usas 'document.ready()' arround '$ ('# trac'). myplugin();'? – powtac

+0

¿Qué quieres que haga el complemento? ¿Por qué estás usando ".live()"? ? – Pointy

+0

Sí, está cargado dentro de document.ready(). –

Respuesta

8

La función ".live()" necesita un selector, y en su complemento no le está dando uno. El objeto jQuery que construyes ($(this)) es un objeto válido pero no incluye una cadena de selector.

Se podría unirse directamente al controlador:

$root.click(function() { ... }); 

Elaborar: usted dice, "... porque raíz y $ $ ('# trac') son exactamente los mismos." El problema es que eso no es realmente cierto. Cuando construye un objeto jQuery con una cadena de selector, el objeto mantiene esa cadena de selector alrededor. No hay una cadena cuando compila "$ root" desde "$ (this)". La función ".live()" opera mediante la creación de un controlador en el elemento <body> y luego prueba el objetivo de cada evento que surge contra ese selector.

+0

¡Gran respuesta! ¡Muchas gracias! –

+0

También me gusta esta respuesta. –

0

me gusta la otra respuesta como una respuesta "directa" a la pregunta, sino mostrar algunas alternativas a lo que está haciendo por los demás creo que se puede simplfy el plugin como:

<div id="mystuff">hi</div> 
<div id='answer'>empty</div> 

$.fn.myplugin = function() { 
    this.live('click', function() { 
     $('#answer').text('here'); 
    }); 
} 
$('#mystuff').myplugin(); 

como se muestra en este ejemplo: http://jsfiddle.net/FgUEB/, así el "this" obtiene el selector y luego puede adjuntar el "clic en vivo" - sin la complejidad del .each - que, si lo hace de la forma en que lo tiene (con el selector fijo por supuesto) pondrá el evento en los elementos varias veces si tiene varios, lo que está implícito en el .each que tiene en su ejemplo.

jQuery.fn.newMethod = function(){ 
    return this.each(function(){ 
     alert(typeof this); 
    }); 
}; 

La referencia a esta palabra clave dentro de la función interna (en la alerta) se refiere al elemento HTML actual. Dado que no es un objeto jQuery no tendrá acceso a los métodos de jQuery (aunque, se puede envolver en el objeto jQuery para conseguir esos métodos atrás como jQuery (este).

jQuery.fn.newMethod = function(){ 
    return this.each(function(){ 
     jQuery(this).css({'background-color':'red'});//each inner element 
    }); 
}; 
Cuestiones relacionadas