2008-09-17 35 views
7

Với ví dụ này:Làm thế nào để chọn các yếu tố liên tiếp phù hợp với một bộ lọc

<img class="a" /> 
<img /> 
<img class="a" /> 
<img class="a" id="active" /> 
<img class="a" /> 
<img class="a" /> 
<img /> 
<img class="a" /> 

(Tôi vừa mới sử dụng thẻ img như một ví dụ, đó không phải là những gì trong mã của tôi)

Sử dụng jQuery, làm thế nào bạn sẽ chọn các thẻ img với lớp "a" tiếp giáp với #active (giữa bốn, trong ví dụ này)? Bạn có thể làm điều đó khá dễ dàng bằng cách lặp qua tất cả các yếu tố sau và trước đó, dừng lại khi điều kiện bộ lọc không thành công, nhưng tôi đã tự hỏi liệu jQuery có thể là nguyên bản không? Không.

Trả lời

4

Đây là những gì tôi nghĩ ra cuối cùng.

// here's our active element. 
var $active = $('#active'); 

// here is the filter we'll be testing against. 
var filter = "img.a"; 

// $all will be the final jQuery object with all the consecutively matched elements. 
// start it out by populating it with the current object. 
var $all = $active; 

for ($curr = $active.prev(filter); $curr.length > 0; $curr = $curr.prev(filter)) { 
    $all = $all.add($curr); 
} 
for ($curr = $td.next(filter); $curr.length > 0; $curr = $curr.next(filter)) { 
    $all = $all.add($curr); 
} 

Đối với một câu hỏi theo dõi, tôi có thể thấy cách này dễ dàng có thể được khái quát hóa bằng cách làm cho nó thành một chức năng mà phải mất hai đối số: một yếu tố ban đầu, và một chuỗi lọc - bất cứ ai có thể chỉ cho tôi đi đúng hướng để tìm hiểu cách mở rộng đối tượng jQuery để thêm một hàm như vậy?


Sửa: Tôi đã kể từ khi phát hiện ra rằng mỗi() chức năng sẽ làm việc này khá tốt đối với một số mục đích. Trong trường hợp của riêng tôi, nó không hoạt động hiệu quả, vì tôi muốn một đối tượng jQuery cho tất cả các phần tử đó, nhưng đây là cách bạn có thể sử dụng cho mỗi mục đích khác nhau (ẩn các phần tử ".a" liên tiếp, trong ví dụ này :)

$('#active') 
    .nextAll() 
    .each(hideConsecutive) 
    .end() 
    .prevAll() 
    .each(hideConsecutive) 
; 
function hideConsecutive(index, element) { 
    var $e = $(element); 
    if (!$e.is(".a")) { 
     return false; // this stops the each function. 
    } else { 
     $e.hide('slow'); 
    } 
} 

-

Edit: tôi đã đặt này lại với nhau thành một plugin bây giờ. Hãy xem http://plugins.jquery.com/project/Adjacent nếu bạn quan tâm.

2

Tôi tin rằng vòng lặp là đặt cược tốt nhất của bạn. Nhưng bạn có thể thử, mỗi hoạt động, và sau đó di chuyển trước và sau cho đến khi điều kiện nghỉ, nếu tập hợp đủ lớn sẽ nhanh hơn.

+0

Bạn có thể cung cấp một số đoạn mã hay không. Nó sẽ là hữu ích vì tôi đã không hoàn toàn nhận được những gì bạn có ý nghĩa. –

0

Đây là một cách khác để làm điều đó, mặc dù câu trả lời anh chị em chọn là khá mát mẻ:

var next = $('#active').next('.a'); 
var prev = $('#active').prev('.a'); 

Edit: Tôi đọc lại yêu cầu của bạn và điều này là không hoàn toàn những gì bạn muốn . Bạn có thể sử dụng nextAll và prevAll, nhưng những người đó cũng sẽ không dừng lại ở IMG mà không có tên lớp.

1

Đoạn mã sau sẽ thêm hai hàm mới, nextConsecutive() và prevConsecutive(). Họ nên làm những gì bạn muốn.

$ .each (['prev', 'next'], chức năng (unusedIndex, name) { $.fn [name + 'Consecutive'] = function (matchExpr) {

var $all = 
     (name == 'prev') 
      ? $(this).prevAll() 
      : $(this).nextAll(); 
    if (!matchExpr) 
     return $all; 

    var $notMatch = $($all).not(matchExpr).filter(':first'); 
    if ($all.index($notMatch) != -1) 
     return $allConsecutive = $all.slice(0, $all.index($notMatch)); 

    return $all; 
}; 

});

Các vấn đề liên quan