2011-12-13 20 views
6

In una tabella con alcune righe nascoste, voglio ottenere la riga visibile successiva, se ne esiste una. Questo farà il lavoro:Trova in modo efficiente la prossima riga della tabella visibile con jQuery

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

ma è molto lento quando molte righe seguono la riga selezionata. Un approccio script è:

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

Questo è molto più veloce, ma ci deve essere un elegante approccio all-jQuery posso usare.

risposta

0

Perché stai utilizzando .nextAll se desideri solo una riga?

Penso che se si sostituisce

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

con

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

si otterrà il miglioramento della velocità che stai cercando.

+0

Grazie per la risposta. Il problema è $ (selectedRow) .next (': visible') prima applica .next() e poi mi dà quella riga successiva se è visibile. Se non è visibile, non ottengo nulla. –

+0

Risposta aggiornata. – Blazemonger

+0

Grazie per aver trovato il tempo di rispondere. Non sapevo su nextUntil(). Ho provato quello che suggerisci, ma non ha funzionato per me perché nextUntil() restituisce un set vuoto se non ci sono righe non visibili tra la riga selezionata e la successiva riga visibile, e sembra che a. set vuoto. Ma la tua guida mi ha portato a qualcosa di meglio di quello che ho avuto, che posterò come risposta alla mia stessa domanda. –

7

Sulla base del suggerimento utile da mblase75, ecco la soluzione più elegante che ho trovato:

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

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

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

Spesso (nel mio caso), la tabella non è filtrata, in modo che la riga successiva è visibile molto del tempo. Quando non lo è, nextUntil() produce un insieme non vuoto di righe non visibili. Selezionando l'ultima riga in quel set e poi la riga successiva che segue, si ottiene la successiva riga visibile nella tabella, se ce n'è una.

1

Appena incontrato esattamente la stessa situazione. Sulla base di risposta di Marshall Morrise, se si vuole un one-liner, si può provare ...

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

Il nuovo po 'qui è la .add(selectedRow) che ci impedisce di cercare di trovare il next() di un elemento vuoto jQuery. Solo il rimanente problema è l'ultimo se nel post di Marshall - sfortunatamente un elemento jQuery vuoto è ancora vero.

0

Ci sono due problemi con uno -liners menzionati in altre risposte:

  1. mancano il caso in cui non ci sono righe invisibili. In tal caso, nextUntil non restituisce alcun elemento. Di seguito è riportato il codice che corregge questo problema.
  2. Se si utilizza un nome di classe specifico, anziché il parametro show/hide predefinito di jQuery, non sembra funzionare in modo affidabile.

Sotto correzioni di codice sia di questioni di cui sopra con le altre risposte:

//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(); 
    } 
} 

Ed ecco il codice per ottenere precedente elemento visibile pure.

//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 breve variante di questo è scrivere:

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

Ciò restituirà partite vuoto se non ci sono elementi visibili, e un elemento specifico altrimenti.

lo uso come questo (in 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") 
Problemi correlati