Làm cách nào để tôi có được cha mẹ cấp n của một phần tử trong jQuery?


151

Khi tôi muốn lấy, ví dụ, cha mẹ cấp 3 của phần tử tôi phải viết $('#element').parent().parent().parent()Có phương pháp nào tối ưu hơn cho việc này không?


2
Tôi muốn chỉ cung cấp số (Cấp) và nhận phần tử, vì phần tử của tôi có thể không có bất kỳ id hoặc tên calss nào
Artur Keyan

1
Nếu bạn có kế hoạch sử dụng lại chức năng này, giải pháp tối ưu là tạo một plugin jQuery.
zzzzBov

3
Xem jsperf.com/jquery-get-3rd-level-parent để biết một số so sánh hiệu suất
a'r

1
Một công cụ tốt khác là hàm ".closest ()". $ ('li.item'). gần nhất ('div') sẽ cung cấp cho bạn DIV là tổ tiên gần nhất của li.item. Tốt cho khi bạn không biết phần tử tăng bao nhiêu cấp, nhưng bạn KHÔNG biết tên thẻ / lớp / thứ gì khác.
Graham

Câu trả lời:


267

cha mẹ () trả về các phần tử tổ tiên được sắp xếp từ gần nhất với các phần tử bên ngoài, bạn có thể xâu chuỗi nó thành eq () :

$('#element').parents().eq(0);  // "Father".
$('#element').parents().eq(2);  // "Great-grandfather".

Tôi có thể sử dụng $ ('# phần tử') này không. cha mẹ () [2]? hoặc phải bằng eq (2)
Artur Keyan

1
điều này sẽ không hoạt động đối với nhiều lựa chọn thành phần, một cách an toàn hơn sẽ là:$('.element').first().parents().eq(num);
zzzzBov

6
@Arthur, bằng cách sử dụng [2]sẽ trả về phần tử DOM bên dưới, sử dụng eq(2)sẽ trả về một đối tượng jQuery.
Frédéric Hamidi

1
@zzzzBov, rất đúng, nhưng sẽ chỉ có một yếu tố được chọn trong trường hợp của người hỏi (vì anh ta khớp với một id).
Frédéric Hamidi

Nếu bạn tìm kiếm trên id "#element", nó sẽ chỉ trả về một phần tử duy nhất vì đó là cách tra cứu ID hoạt động, chúng sẽ trả về phần tử đầu tiên có ID đó trong dom. Mặt khác, nếu bạn đã làm "div # phần tử" hoặc một bộ chọn lớp, bạn sẽ đúng.
Henry

29

Tùy thuộc vào nhu cầu của bạn, nếu bạn biết cha mẹ bạn đang tìm kiếm gì, bạn có thể sử dụng bộ chọn .parents ().

TRỨNG: http://jsfiddle.net/HenryGarle/Kyp5g/2/

<div id="One">
    <div id="Two">
        <div id="Three">
            <div id="Four">

            </div>
        </div>
    </div>
</div>


var top = $("#Four").parents("#One");

alert($(top).html());

Ví dụ sử dụng chỉ mục:

//First parent - 2 levels up from #Four
// I.e Selects div#One
var topTwo = $("#Four").parents().eq(2);

alert($(topTwo ).html());

Bây giờ tôi theo cách này, nhưng tôi muốn đưa ra cấp độ
Artur Keyan

3
Đọc thêm câu trả lời và tất cả sẽ được tiết lộ! (Tôi đã cho bạn ví dụ về cấp độ)
Henry

Điều này hoạt động độc đáo cho tất cả các loại bộ chọn khác. Ví dụ, nếu bạn muốn danh sách tất cả cha mẹ và cha mẹ của cha mẹ với một lớp nhất định, điều này sẽ trả lại cho họ.
darksky

8

Bạn có thể cung cấp cho cha mẹ đích một id hoặc lớp (ví dụ myParent) và tham chiếu với $('#element').parents(".myParent")


Tôi muốn chỉ cung cấp số và nhận phần tử, vì phần tử của tôi có thể không có bất kỳ id hoặc tên calss nào
Artur Keyan

6

Một cách nhanh hơn là sử dụng javascript trực tiếp, ví dụ.

var parent = $(innerdiv.get(0).parentNode.parentNode.parentNode);

Điều này chạy nhanh hơn đáng kể trên trình duyệt của tôi so với .parent()các cuộc gọi jQuery .

Xem: http://jsperf.com/jquery-get-3rd-level-parent


Bằng cách "nhanh hơn đáng kể", chúng tôi đang xem xét về một mức độ lớn về sự khác biệt về tốc độ (chạy jQuery 1.10.1 trên Chrome 51). Chắc chắn đáng thực hiện nếu bạn đang điều chỉnh tốc độ.
Iain Fraser

5

Không tìm thấy câu trả lời nào bằng cách sử dụng closest() và tôi nghĩ đó là câu trả lời đơn giản nhất khi bạn không biết có bao nhiêu cấp độ của phần tử được yêu cầu, vì vậy hãy đăng câu trả lời:
Bạn có thể sử dụng closest()chức năng kết hợp với bộ chọn để có được phần tử đầu tiên phù hợp khi di chuyển lên trên từ phần tử:

('#element').closest('div')    // returns the innermost 'div' in its parents
('#element').closest('.container')    // returns innermost element with 'container' class among parents
('#element').closest('#foo')    // returns the closest parent with id 'foo'

3

Thật đơn giản. Chỉ dùng

$(selector).parents().eq(0); 

trong đó 0 là cấp độ cha mẹ (0 là cha mẹ, 1 là cha mẹ của cha mẹ, v.v.)


3

Chỉ cần thêm :eq()bộ chọn như thế này:

$("#element").parents(":eq(2)")

Bạn chỉ cần xác định chỉ mục mà cha mẹ: 0 cho cha mẹ ngay lập tức, 1 cho cha mẹ lớn, ...


Cách này là cách nhanh nhất để hoàn thành công việc. Đây là điểm chuẩn để chứng minh điều đó: jsperf.com/jquery-get-element-s-nth-parent
java-man-script

3

Nếu bạn có kế hoạch sử dụng lại chức năng này, giải pháp tối ưu là tạo một plugin jQuery:

(function($){
$.fn.nthParent = function(n){
  var $p = $(this);
  while ( n-- >= 0 )
  {
    $p = $p.parent();
  }
  return $p;
};
}(jQuery));

Tất nhiên, bạn có thể muốn mở rộng nó để cho phép một bộ chọn tùy chọn và những thứ khác.

Một lưu ý: điều này sử dụng một 0chỉ mục dựa trên cha mẹ, vì vậy nthParent(0)cũng giống như gọi điện thoại parent(). Nếu bạn muốn 1lập chỉ mục dựa trên, hãy sử dụngn-- > 0


Tôi nghĩ bạn sẽ tìm thấy phần này nhanh hơn: var p = 1 + n; while (p--) { $p = $p.parent(); }và NẾU bạn muốn thay đổi thành 1 dựa trên, Javascript là "falsey" bạn có thể sử dụng: while (n--) { $p = $p.parent();} lưu một kiểm tra có điều kiện
Mark Schultheiss

@Mark Schultheiss, Nó không chỉ là về tốc độ, mà còn về độ tin cậy. Điều gì xảy ra với chức năng của bạn nếu ai đó thờ ơ gọi nthParent(-2)? Ví dụ của bạn bị hỏng.
zzzzBov

HOẶC chỉ cần quay lại(function($) { $.fn.nthParent = function(n) { return $(this).parents().eq(n); }; }(jQuery));
Mark Schultheiss

@Mark Schultheiss, một lần nữa, độ tin cậy. Hàm của tôi trả về nthParent cho mọi phần tử trong vùng chọn, hàm của bạn trả về phần tử thứ n trong danh sách parentssẽ không chính xác cho các lựa chọn có nhiều hơn một phần tử.
zzzzBov

đúng về -2, và như trong ví dụ của bạn, sử dụng var p = n >? (1 + n):1; thay vào đó sẽ trả về cha mẹ đầu tiên trong trường hợp đó thay vì "không có gì" - hoặc khi nó phá vỡ vòng lặp trong ví dụ của tôi. VÌ VẬY, có lẽ nên là: (function($) { $.fn.nthParent = function(n) { var $p = $(this); if (!(n > -0)) { return $() }; var p = 1 + n; while (p--) { $p = $p.parent(); } return $p; }; }(jQuery)); nếu bạn không muốn trả lại bất cứ điều gì.
Mark Schultheiss

3

Nếu bạn có div cha mẹ chung, bạn có thể sử dụng liên kết ParentUntil ()

ví dụ: $('#element').parentsUntil('.commonClass')

Ưu điểm là bạn không cần phải nhớ có bao nhiêu thế hệ giữa phần tử này và phần tử chung (được xác định bởi lớp chung).


1

bạn cũng có thể dùng :

$(this).ancestors().eq(n) 

ví dụ: $(this).ancestors().eq(2)-> cha mẹ của cha mẹ của this.


0

Bạn có thể sử dụng một cái gì đó như thế này:

(function($) {
    $.fn.parentNth = function(n) {
        var el = $(this);
        for(var i = 0; i < n; i++)
            el = el.parent();

        return el;
    };
})(jQuery);

alert($("#foo").parentNth(2).attr("id"));

http://jsfiddle.net/Xeon06/AsNUu/


1
Không phải downvoter, nhưng đây có lẽ là giải pháp tồi tệ nhất (tức là không hiệu quả) ở đây.
zatatatata

0

bằng cách sử dụng eq để lấy DOM động trong khi sử dụng .parent (). Parent () dường như lấy DOM đã được tải ban đầu (nếu điều đó thậm chí có thể).

Tôi sử dụng cả hai trên một phần tử có các lớp được áp dụng cho onmouseover. eq hiển thị các lớp trong khi .parent (). Parent () không.


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.