2010-11-04 28 views
9

phép nói rằng tôi có cấu trúc DOM nàyTìm phụ huynh chia sẻ đầu tiên của hai yếu tố

<body> 
    <p> 
     Hello 
     <i>how <b>are</b> you</i> 
     and 
     <i>what <b>are <tt>you</tt> going</b> to</i> 
     eat tonight? 
    </p> 
</body> 

Sử dụng jQuery Tôi muốn làm quen với các mẹ chia sẻ FIRST của

<b>are</b> 

<tt>you</tt> 

Từ trên xuống, đây sẽ là < p> không phải là thẻ < body>.

Bất kỳ ý tưởng nào về cách xác định cha mẹ dùng chung đầu tiên sử dụng jQuery?

+0

tổ tiên chung gần đây nhất. Cảm thấy như tôi đang nghiên cứu di truyền học hay gì đó! – jball

Trả lời

9

Như thế này:

$(a).parents().filter(function() { return jQuery.contains(this, b); }).first(); 

Nếu b là một chọn (như trái ngược với một phần tử DOM), bạn có thể thay đổi nó thành:

$(a).closest(':has(b)'); 

Đây là ngắn hơn, nhưng chậm hơn đáng kể.

Thứ tự của ab không liên quan; nếu b gần với phụ huynh hơn, nó sẽ nhanh hơn.

+0

Điều này sẽ không hoạt động, bạn có thể kiểm tra ở đây: http://www.jsfiddle.net/nick_craver/a7hgu/ bạn phải 'trả về' trong hàm' .filter() 'để nhận bất kỳ kết quả nào. –

+0

@Nick: Đã sửa lỗi; cảm ơn. Tôi nghi ngờ rằng điều này sẽ nhanh hơn phiên bản của bạn, vì 'contains' gọi một phương thức riêng (xem nguồn jQuery). Tôi quá lười để kiểm tra. – SLaks

+0

@SLaks - * Nếu * trình duyệt hỗ trợ nó có, mặc dù bạn không thể sử dụng bộ chọn trực tiếp tại đây để nó hơi lộn xộn hơn, phụ thuộc vào những gì bạn đang làm với nó (trong vòng lặp hay không). Chỉ cần một ý nghĩ: sẽ tốt ở đây nếu '.closest()' lấy một tập hợp các phần tử để lọc khi nó đi ... –

5

Bạn có thể kết hợp với .parents().filter(), như thế này:

$("b:first").parents().filter($("tt").parents()).first() 
//or more generic: 
$(elem1).parents().filter($(elem2).parents()).first() 

này được tất cả cha mẹ chia sẻ, sau đó bạn có thể đi .first() hoặc .last() ... bất cứ điều gì cần thiết.

You can test it here. Lưu ý rằng điều này nhanh hơn nhiều so với .has() vì chúng tôi chỉ so sánh 2 tập hợp phần tử DOM, không so sánh nhiều so với nhiều tập hợp phần tử DOM. Ngoài ra, tập hợp kết quả sẽ theo thứ tự đi lên tài liệu, trong ví dụ này <p> rồi <body>.

+1

Tốt hơn là đi bộ cây lên gốc và cố gắng tìm ra trận đấu đầu tiên hơn là thực hiện tìm kiếm đầy đủ trong mọi cây con. – Gumbo

0

Non-jQuery phiên bản:

var arrayContains = Array.prototype.indexOf ? 
    function(arr, val) { 
     return arr.indexOf(val) > -1; 
    }: 

    function(arr, val) { 
     var i = arr.length; 
     while (i--) { 
      if (arr[i] === val) { 
       return true; 
      } 
     } 
     return false; 
    }; 


function getCommonAncestor(node1, node2) { 
    var ancestors = [], n; 
    for (n = node1; n; n = n.parentNode) { 
     ancestors.push(n); 
    } 

    for (n = node2; n; n = n.parentNode) { 
     if (arrayContains(ancestors, n)) { 
      return n; 
     } 
    } 

    return null; 
} 
0

Dưới đây là một giải pháp không jquery rất đơn giản:

function sharedParent (elem1, elem2) { 
for (; elem1!= null; elem1=elem1.parentNode) { 
    for (var e2=elem2; e2!= null; e2=e2.parentNode) 
    if (elem1 == e2) return elem1; 
    } 
return null; 
} 
0
jQuery(function(){ 

    var elem1 = jQuery("#a"); 
    var elem2 = jQuery("#b"); 

    var foo1 = elem1.parents().has(elem2).first().attr("tagName"); 
    var foo2 = elem1.closest(":has(" + elem2.selector + ")").first().attr("tagName"); 

    alert(foo1); 
    alert(foo2); 


}); 

JSBIN

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