2011-12-13 30 views
6

Trong một bảng có một số hàng bị ẩn, tôi muốn có hàng hiển thị tiếp theo, nếu có hàng. Việc này sẽ thực hiện công việc:Hiệu quả tìm hàng tiếp theo có thể nhìn thấy trong bảng với jQuery

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

nhưng rất chậm khi nhiều hàng theo hàng được chọn. Một cách tiếp cận theo kịch bản là:

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

Điều này nhanh hơn nhiều, nhưng có một cách tiếp cận tất cả jQuery thanh lịch mà tôi có thể sử dụng.

Trả lời

0

Tại sao bạn sử dụng .nextAll nếu bạn chỉ muốn một hàng?

Tôi nghĩ rằng nếu bạn thay thế

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

với

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

bạn sẽ nhận được sự cải thiện tốc độ mà bạn đang tìm kiếm.

+0

Cảm ơn bạn đã trả lời. Vấn đề là $ (selectedRow) .next (': visible') đầu tiên áp dụng .next() và sau đó cung cấp cho tôi hàng tiếp theo nếu nó hiển thị. Nếu nó không nhìn thấy được, tôi chẳng nhận được gì cả. –

+0

Đã cập nhật câu trả lời. – Blazemonger

+0

Cảm ơn bạn đã dành thời gian trả lời. Không biết về nextUntil(). Tôi đã thử những gì bạn đề nghị, nhưng nó không làm việc cho tôi vì nextUntil() trả về một tập rỗng nếu không có hàng không nhìn thấy được giữa hàng đã chọn và hàng hiển thị tiếp theo, và .next dường như được áp dụng cho bộ trống. Nhưng hướng dẫn của bạn đưa tôi đến một cái gì đó tốt hơn so với những gì tôi đã có, mà tôi sẽ đăng như là một câu trả lời cho câu hỏi của riêng tôi. –

7

Dựa trên những gợi ý hữu ích từ mblase75, đây là giải pháp thanh lịch nhất mà tôi đã tìm thấy:

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

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

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

Thường (trong trường hợp của tôi), bảng được không được lọc, vì vậy hàng tiếp theo có thể nhìn thấy nhiều thời gian. Khi không, nextUntil() tạo ra một tập rỗng các hàng không nhìn thấy được. Chọn hàng cuối cùng trong tập hợp đó và sau đó hàng tiếp theo sau nó sẽ hiển thị hàng tiếp theo có thể nhìn thấy trong bảng, nếu có.

1

Chỉ cần chạy chính xác cùng một tình huống. Dựa trên câu trả lời Marshall Morrise, nếu bạn muốn có một one-liner, bạn có thể thử ...

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

Các bit mới đây là .add(selectedRow) mà ngăn cản chúng ta cố gắng để tìm ra next() của một phần tử jQuery trống. Chỉ còn lại vấn đề là vấn đề cuối cùng nếu trong bài viết của Marshall - không may là một phần tử jQuery trống vẫn còn trung thực.

0

Có hai vấn đề với một -liners đề cập trong câu trả lời khác:

  1. Họ bỏ lỡ trường hợp khi không có hàng vô hình. Trong trường hợp đó, nextUntil không trả về bất kỳ phần tử nào. Dưới đây là mã sửa lỗi này.
  2. Nếu bạn đang sử dụng tên lớp cụ thể, thay vì hiển thị/ẩn mặc định của jQuery thì có vẻ như nó không hoạt động đáng tin cậy.

Dưới sửa đang cả hai vấn đề trên với câu trả lời khác:

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

Và đây là đoạn code để có được yếu tố có thể nhìn thấy trước là tốt.

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

Một biến thể ngắn của việc này là để viết:

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

này sẽ trả về một trận đấu có sản phẩm nào nếu không có yếu tố hữu hình, và một yếu tố cụ thể khác.

tôi sử dụng nó như thế này (trong 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") 
Các vấn đề liên quan