2011-05-13 14 views
5

Tengo algunos problemas para adjuntar manejadores de eventos en vivo a filas particulares.jQuery Traversing + Controladores de eventos en vivo


lo que tengo y lo que busco:

tengo algo de HTML que se genera dinámicamente tras página carga de la siguiente manera:

<table> 
    <tr> 
     <td></td> 
    </tr> 
    <tr> 
     <td class="bonus"></td> 
    </tr> 
    <tr> 
     <td></td> 
    </tr> 
</table> 

me gustaría tener dos eventos click:

  1. Uno de filas que no son una "fila de bonificación"
  2. Uno de filas que tienen una "fila de bonificación" después de ellos

lo que he tratado y el problema:

Sin embargo, no puedo entender cómo usar un selector para seleccionar "elemento que tiene un elemento particular después de él" (es decir, un selector "anterior"). Por lo tanto, lo mejor que puedo llegar a decir:

  1. filas que no son una "fila" bonificación: $('tr:not(:has(.bonus))')
  2. filas que tienen una "fila de bonificación" después de ellos: $('tr + tr:has(.bonus)').prev()

esto es todo bien y bueno, excepto cada vez que use el método live() en un objeto jQuery que se obtuvo a través de recorrido, en lugar de la selección puro es decir

$('tr:has(.bonus)').prev().live('click', function() { 
    alert('hello'); 
}); 

me sale este error:

uncaught exception: Syntax error, unrecognized expression:)


La cuestión como un ejemplo aún más mínimos:

Estaba esperando que esto se localizó en una secuencia de comandos que estoy usando, pero me he aislado de este a un ejemplo jsFiddle mínima que todavía replica el problema para mí: http://jsfiddle.net/ptvrA/

HTML:

<div></div> 
<div id="target"></div> 

JS:

$('#target').prev().live('click', function() { 
    alert('f'); 
}); 

Al parecer, de this answer que esto es una limitación conocida de live.


Mis soluciones

Como referencia, mis soluciones son o bien:

  1. Marque las filas que tienen una "fila de bonificación" después de alguna manera
  2. Enlace el click a todas las filas, y verifique si hay una "fila de bonificación" después de ellas dentro del controlador.

Pero si puedo conseguir una solución "mejor", incluso por curiosidad en caso de que me encuentro con este problema en una situación diferente, se lo agradecería.

Saludos

+1

Lo que es interesante es que si usas el selector '$ ('tr: has (.bonus)'). Prev ('tr')' no causa el error de sintaxis ... pero tampoco funciona . – mVChr

Respuesta

1

Para ser honesto, yo sólo tiene que utilizar su segunda idea y se unen clic para todas las filas, a continuación, comprobar para ver si la próxima fila tiene un td bonificación en ella, así:

$('tr:not(:has(.bonus))').live('click', function() { 
    if ($(this).next().children('td').hasClass('bonus')) { 
     alert('next row has bonus td'); 
    } 
    else { 
     alert('next row does not have bonus td'); 
    } 
}); 

violín que se encuentra aquí : http://jsfiddle.net/7gdqc/2/

No creo que haya una forma de selección pura para hacerlo, y esto no es realmente una solución alternativa, lo llamaría una solución válida para su problema.

+0

Hola Christian, ¡con eso me he pasado tan bien que no estaba loco por encauzarme en esa dirección! –

+0

En realidad, acabo de editarlo para que solo vincule el clic a filas que no tienen una bonificación (como su ejemplo), si no necesita esas filas manejadas. A veces solo tienes que hacer cosas sin selectores puros: p –

2
$('tr + tr:has(.bonus) ~ tr') //for row whose next sibling is a bonus row 

va a hacer lo que quiera con el método .live.

Para todas las personas que llegan aquí en el futuro usando Google.

uncaught exception: Syntax error, unrecognized expression:) 

que está pasando porque .live() utiliza el selector original que se le dio a la primera llamada en la cadena de jQuery. No tiene en cuenta los métodos adicionales utilizados después del $ inicial ('selector').

+0

Hola wewals, sí, esto funciona (bueno, en realidad, creo que el bit '$ (e.target) .parent ('tr')' debería tener errores de uso, pero la idea es sólida) y ya se menciona en mis soluciones. En realidad, no resuelve el problema original (ya que esto termina vinculando eventos de clics a todos los elementos 'tr', incluso si filtramos dentro del controlador). –

+1

Tiene razón acerca de la llamada .parent(). – wewals

+1

Sin embargo, vale la pena mencionar que Live solo ata un manejador de eventos único, alguna vez. Es un evento vinculado al cuerpo que realiza una comprobación de e.getget muy similar a la que escribí para verificar contra el primer selector pasado al objeto jquery al que se agrega la llamada .live. Entonces no vas a ser vinculante para cada tr elemento. Esta es la razón por la cual se recomienda mucho vivir. – wewals

Cuestiones relacionadas