2011-12-13 10 views
6

En una tabla con algunas filas ocultas, quiero obtener la siguiente fila visible, si existe. Esto hará el trabajo:Encuentra de manera eficiente la siguiente fila de la tabla visible con jQuery

row = $(selectedRow).nextAll(':visible'); 
if ($(row).length > 0) 
    selectedRow = row; 

pero es muy lento cuando muchas filas siguen la fila seleccionada. Un enfoque guión es:

var row = $(selectedRow).next(); 
while ($(row).length > 0 && !$(row).is(':visible')) 
    row = $(row).next(); 
if ($(row).length > 0) 
    selectedRow = row; 

Esto es mucho más rápido, pero no tiene que ser un enfoque de todo jQuery elegante que puedo usar.

Respuesta

0

¿Por qué está usando .nextAll si solo quiere una fila?

creo que si se reemplaza

row = $(selectedRow).nextAll(':visible'); 

con

row = $(selectedRow).nextUntil(':visible').next(); 

que obtendrá la mejora de la velocidad que usted está buscando.

+0

Gracias por la respuesta. El problema es $ (selectedRow) .next (': visible') primero aplica .next() y luego me da la siguiente fila si es visible. Si no es visible, no obtengo nada. –

+0

Respuesta actualizada. – Blazemonger

+0

Gracias por tomarse el tiempo para responder. No sabía acerca de nextUntil(). Intenté con lo que sugieres, pero no me funcionó porque nextUntil() devuelve un conjunto vacío si no hay filas no visibles entre la fila seleccionada y la siguiente fila visible, y el .next parece aplicarse a ese conjunto vacio. Pero su guía me llevó a algo mejor de lo que tenía, que publicaré como respuesta a mi propia pregunta. –

7

Sobre la base de la sugerencia útil de mblase75, aquí es la solución más elegante que he encontrado:

var row = $(selectedRow).next(':visible'); 

if ($(row).length == 0) 
    row = $(selectedRow).nextUntil(':visible').last().next(); 

if ($(row).length > 0) 
    selectedRow = row; 

menudo (en mi caso), la tabla no se filtra, por lo que la siguiente fila es visible La mayoria del tiempo. Cuando no lo es, nextUntil() produce un conjunto no vacío de filas no visibles. Al seleccionar la última fila de ese conjunto y luego la siguiente fila, se obtiene la siguiente fila visible de la tabla, si es que hay una.

1

Acabo de encontrar exactamente la misma situación. Sobre la base de la respuesta de Marshall Morrise, si quieres una sola línea, puede intentar ...

selectedRow = $(selectedRow).nextUntil(':visible').add(selectedRow).last().next(); 

El nuevo poco aquí es la .add(selectedRow) que nos impide tratar de encontrar el next() de un elemento jQuery vacía. El único problema restante es el último si está en la publicación de Marshall; desafortunadamente, un elemento jQuery vacío aún es cierto.

0

Hay dos problemas con uno -liners mencionado en otras respuestas:

  1. se pierden el caso cuando no hay filas invisibles. En ese caso, nextUntil no devuelve ningún elemento. A continuación se muestra el código que soluciona este problema.
  2. Si está utilizando un nombre de clase específico, en lugar del show/hide predeterminado de jQuery, tampoco parece funcionar de manera confiable.

A continuación los arreglos de código tanto de los problemas anteriores con otras respuestas:

//invisibleRowClassName parameter is optional 
function nextVisibleSibling(element, invisibleRowClassName) { 
    var selector = invisibleRowClassName ? (":not(." + invisibleRowClassName + ")") : ".visible"; 
    var invisibleElements = element.nextUntil(selector); 
    if (invisibleElements.length === 0) { 
     return element.next(); 
    } 
    else { 
     return invisibleElements.last().next(); 
    } 
} 

Y aquí está el código para obtener elemento visible anterior también.

//invisibleRowClassName parameter is optional 
function prevVisibleSibling(element, invisibleRowClassName) { 
    var selector = invisibleRowClassName ? (":not(." + invisibleRowClassName + ")") : ".visible"; 
    var invisibleElements = element.prevUntil(selector); 
    if (invisibleElements.length === 0) { 
     return element.prev(); 
    } 
    else { 
     return invisibleElements.last().prev(); 
    } 
} 
0

Una variante corta de esto es escribir:

$(element).nextAll().filter(":visible:first") 

Esto devolverá una coincidencia vacía si no hay elementos visibles, y un elemento específico de otra manera.

lo uso como esto (en CoffeeScript):

$(input_element).on "keydown", (e) -> 
    if e.which == 40 # Down key 
     new_selected = $(selected_element).nextAll().filter(":visible:first") 
     if new_selected.length 
      $(selected_element).removeClass("selected") 
      new_selected.addClass("selected") 

    if e.which == 38 # Up key 
     new_selected = $(selected_element).prevAll().filter(":visible:first") 
     if new_selected.length 
      $(selected_element).removeClass("selected") 
      new_selected.addClass("selected") 
Cuestiones relacionadas