Effectively find the next visible row of a table using jQuery

In a table with hidden rows, I want to get the next visible row, if it exists. This will do the job:

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

but it is very slow when many lines follow the selected line. Scenario:

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

This is much faster, but there should be an elegant all-jQuery approach that I can use.

+6
source share
5 answers

Based on a useful suggestion from mblase75, here is the most elegant solution I found:

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

Often (in my case) the table is not filtered, so the next row is visible most of the time. When this is not the case, nextUntil () gives a non-empty set of invisible strings. Selecting the last row in this set and then the next row following it gives the next visible row in the table, if any.

+7
source

Just ran into the same situation. Based on Marshall Morris's answer, if you want one liner, you can try ...

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

The new bit here is .add(selectedRow) , which prevents us from finding next() empty jQuery element. Only the remaining problem is the last, if the Marshall post is unfortunately the empty jQuery element is still true.

+1
source

Why are you using .nextAll if you only need one line?

I think if you replace

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

from

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

You will get the improved speed you are looking for.

0
source

There are two problems with the one-liner mentioned in the other answers:

  • They skip the case where there are no invisible lines. In this case, nextUntil does not return any elements. Below is the code that fixes this problem.
  • If you use a specific class name, instead of the default show / hide jQuery, then it also does not work reliably.

The code below fixes both of the above questions with other answers:

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

And here is the code to get the previous visible element.

 //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
source

One short option is to write:

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

This will return a null match if there are no visible elements in it, otherwise a specific element.

I use it like this (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") 
0
source

Source: https://habr.com/ru/post/903711/


All Articles