2009-12-01 27 views
16

Tiếp theo, trước tiên, tiếp theoTất cả và phương pháp prevAll rất hữu ích, nhưng không phải nếu các yếu tố bạn đang tìm không có cùng yếu tố cha. Những gì tôi muốn làm là một cái gì đó như thế này:jQuery tìm các phần tử kế tiếp/trước của một lớp nhất định nhưng không nhất thiết là anh chị em

<div> 
    <span id="click">Hello</span> 
</div> 
<div> 
    <p class="find">World></p> 
</div> 

Khi nhịp với id click được nhấn, tôi muốn để phù hợp với phần tử tiếp theo với lớp find, mà trong trường hợp này không phải là một anh chị em ruột của nhấp nên next() hoặc nextAll() sẽ không hoạt động.

+0

có thể trùng lặp của [jQuery để tìm tất cả các phần tử trước khớp với biểu thức] (http://stackoverflow.com/questions/322912/jquery-to-find-all-previous-elements-that-match- an-expression) – sachleen

Trả lời

8

Tôi đã làm việc về vấn đề này bản thân mình ngày hôm nay, đây là những gì tôi đã đưa ra:

/** 
* Find the next element matching a certain selector. Differs from next() in 
* that it searches outside the current element's parent. 
* 
* @param selector The selector to search for 
* @param steps (optional) The number of steps to search, the default is 1 
* @param scope (optional) The scope to search in, the default is document wide 
*/ 
$.fn.findNext = function(selector, steps, scope) 
{ 
    // Steps given? Then parse to int 
    if (steps) 
    { 
     steps = Math.floor(steps); 
    } 
    else if (steps === 0) 
    { 
     // Stupid case :) 
     return this; 
    } 
    else 
    { 
     // Else, try the easy way 
     var next = this.next(selector); 
     if (next.length) 
      return next; 
     // Easy way failed, try the hard way :) 
     steps = 1; 
    } 

    // Set scope to document or user-defined 
    scope = (scope) ? $(scope) : $(document); 

    // Find kids that match selector: used as exclusion filter 
    var kids = this.find(selector); 

    // Find in parent(s) 
    hay = $(this); 
    while(hay[0] != scope[0]) 
    { 
     // Move up one level 
     hay = hay.parent();  
     // Select all kids of parent 
     // - excluding kids of current element (next != inside), 
     // - add current element (will be added in document order) 
     var rs = hay.find(selector).not(kids).add($(this)); 
     // Move the desired number of steps 
     var id = rs.index(this) + steps; 
     // Result found? then return 
     if (id > -1 && id < rs.length) 
      return $(rs[id]); 
    } 
    // Return empty result 
    return $([]); 
} 

Vì vậy, trong ví dụ của bạn

<div><span id="click">hello</span></div> 
<div><p class="find">world></p></div> 

bây giờ bạn có thể tìm và thao tác các yếu tố 'p' sử dụng

$('#click').findNext('.find').html('testing 123'); 

Tôi nghi ngờ nó sẽ hoạt động tốt trên cấu trúc lớn, nhưng ở đây là :)

+0

Không hoạt động nếu phần tử bạn muốn chọn là anh chị em. Và nó khai báo biến "hay" toàn cục. –

+1

Và ai sẽ sửa đổi điều này để tìm Trước? – Relm

+0

được viết rất tốt! –

0

Tôi nghĩ cách duy nhất để giải quyết vấn đề này là thực hiện tìm kiếm đệ quy trên các phần tử sau phần tử hiện tại. Không có giải pháp đơn giản cho vấn đề này được cung cấp bởi jQuery. Nếu bạn chỉ muốn tìm các phần tử trong các anh chị em của phần tử cha mẹ của bạn (như trường hợp trong ví dụ của bạn), thì không bắt buộc phải thực hiện tìm kiếm đệ quy, nhưng bạn phải thực hiện nhiều tìm kiếm.

Tôi đã tạo một ví dụ (thực ra, nó không phải đệ quy) làm những gì bạn muốn (tôi hy vọng). Nó sẽ chọn tất cả các yếu tố sau yếu tố nhấp hiện tại và làm cho họ đỏ:

<script type="text/javascript" charset="utf-8"> 
    $(function() { 
     $('#click').click(function() { 
      var parent = $(this); 
      alert(parent); 
      do { 
       $(parent).find('.find').css('background-color','red'); 
       parent = $(parent).parent(); 
      } while(parent !== false); 
     }); 
    }); 
</script> 
0

Các biểu thức sau đây nên (trừ các lỗi cú pháp!) Tìm tất cả các anh chị em của cha mẹ có chứa một yếu tố p.find và sau đó tìm những p.find yếu tố và sự thay đổi màu xanh lam.

$(this).parent().nextAll(":has(p.find)").find(".find").css('background-color','blue'); 

Tất nhiên, nếu cấu trúc trang của bạn là như vậy mà p.find xảy ra ở một mức độ hoàn toàn khác nhau của hệ thống phân cấp (anh chị em ruột của ông bà chẳng hạn), nó sẽ không làm việc.

3

Giải pháp của tôi sẽ liên quan đến việc điều chỉnh đánh dấu của bạn một chút để làm cho jQuery dễ dàng hơn nhiều. Nếu điều này là không thể hoặc không phải là một câu trả lời hấp dẫn, xin vui lòng bỏ qua!

tôi sẽ quấn một wrapper 'mẹ' xung quanh những gì bạn muốn làm ...

<div class="find-wrapper"> 
    <div><span id="click">hello</span></div> 
    <div><p class="find">world></p></div> 
</div> 

Bây giờ, để tìm find:

$(function() { 
    $('#click').click(function() { 
     var $target = $(this).closest('.find-wrapper').find('.find'); 
     // do something with $target... 
    }); 
}); 

này mang đến cho bạn sự linh hoạt để có bất cứ điều gì loại đánh dấu và phân cấp bạn muốn bên trong trình bao bọc mà tôi đã đề xuất và vẫn tìm thấy mục tiêu của bạn một cách đáng tin cậy.

Chúc may mắn!

13

Hãy thử điều này. Nó sẽ đánh dấu Element của bạn, tạo một tập hợp các yếu tố phù hợp với bộ chọn của bạn và thu thập tất cả các yếu tố từ tập hợp sau phần tử của bạn.

$.fn.findNext = function (selector) { 
    var set = $([]), found = false; 
    $(this).attr("findNext" , "true"); 
    $(selector).each(function(i , element) { 
     element = $(element); 
     if (found == true) set = set.add(element) 
     if (element.attr("findNext") == "true") found = true; 
    }) 
    $(this).removeAttr("findNext") 
    return set 
} 

EDIT

đơn giản hơn nhiều giải pháp sử dụng jquerys phương pháp chỉ số. các yếu tố bạn gọi phương thức từ nhu cầu để được lựa chọn bằng cách chọn tương tự mặc dù

$.fn.findNext = function(selector){ 
    var set = $(selector); 
    return set.eq(set.index(this,) + 1) 
} 

để giải phóng hàm từ tàn tật này, chúng ta có thể youse các trình duyệt sở hữu compareDocumentposition

$.fn.findNext = function (selector) { 
    // if the stack is empty, return the first found element 
    if (this.length < 1) return $(s).first(); 
    var found, 
     that = this.get(0); 
    $(selector) 
    .each(function() { 
     var pos = that.compareDocumentPosition(this); 
     if (pos === 4 || pos === 12 || pos === 20){ 
     // pos === 2 || 10 || 18 for previous elements 
     found = element; 
     return false; 
     }  
    }) 
    // using pushStack, one can now go back to the previous elements like this 
    // $("#someid").findNext("div").remove().end().attr("id") 
    // will now return "someid" 
    return this.pushStack([ found ]); 
}, 

EDIT 2 điều này dễ dàng hơn nhiều khi sử dụng $ .grep của jQuery. đây là mã mới

$.fn.findNextAll = function(selector){ 
     var that = this[ 0 ], 
      selection = $(selector).get(); 
     return this.pushStack(
     // if there are no elements in the original selection return everything 
     !that && selection || 
     $.grep(selection, function(n){ 
      return [4,12,20].indexOf(that.compareDocumentPosition(n)) > -1 
     // if you are looking for previous elements it should be [2,10,18] 
     }) 
    ); 
    } 
    $.fn.findNext = function(selector){ 
     return this.pushStack(this.findNextAll(selector).first()); 
    } 

khi nén tên biến này trở thành hai lớp lót.

Chỉnh sửa 3 sử dụng thao tác bitwise, chức năng này thậm chí có thể nhanh hơn?

$.fn.findNextAll = function(selector){ 
    var that = this[ 0 ], 
    selection = $(selector).get(); 
    return this.pushStack(
    !that && selection || $.grep(selection, function(n){ 
     return that.compareDocumentPosition(n) & (1<<2); 
     // if you are looking for previous elements it should be & (1<<1); 
    }) 
); 
} 
$.fn.findNext = function(selector){ 
    return this.pushStack(this.findNextAll(selector).first()); 
} 
+0

một bất lợi mà tôi nghĩ là phần tử bạn gọi findNext từ, cần phải được chọn bởi cùng một bộ chọn, nếu không nó sẽ chỉ lặp qua mọi thứ mà không tìm thấy phần tử đã đánh dấu của bạn. – lordvlad

+0

Cảm ơn bạn, tôi đã xem xét tất cả và không ai khác đã trả lời trường hợp không anh chị em như ngắn gọn như bạn. –

+0

Cảm ơn bạn đã làm việc. Với các tài liệu dạng bảng rất lớn, Chỉnh sửa 2 đã tăng tốc những gì tôi đã cố gắng làm theo thứ tự độ lớn! – David

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