Đứa con đầu tiên của jQuery này


317

Tôi đang cố gắng chuyển "cái này" từ một khoảng được nhấp vào một hàm jQuery để có thể thực thi jQuery trên đứa con đầu tiên của phần tử được nhấp đó. Dường như không thể hiểu đúng ...

<p onclick="toggleSection($(this));"><span class="redClass"></span></p>

Javascript:

function toggleSection(element) {
  element.toggleClass("redClass");
}

Làm thế nào để tôi tham khảo: con đầu tiên của yếu tố?


4
Nếu bạn đang sử dụng jQuery, tại sao bạn không liên kết trình xử lý sự kiện bằng jQuery?
Vivin Paliath

2
bởi vì các trình xử lý sự kiện liên kết phải được khởi tạo trong document. yet () để thêm hiệu năng (đây là một ứng dụng cho IE6). Hoặc là có một cách khác?
macca1

Hừm .. không chắc. Liên kết bằng jQuery là cách tiêu chuẩn (nếu bạn đã sử dụng jQuery). Những loại hiệu suất bạn đang gặp phải khi bạn sử dụng jQuery(document).ready(...)?
Vivin Paliath

Đây là một ứng dụng lớn với hơn 7 nhà phát triển. Ban đầu chỉ hơn 4 giây trước khi tôi cố gắng dọn dẹp nó một chút. Vì vậy, tôi muốn tránh thêm nhiều hơn vào nó khi tôi không phải :)
macca1

Câu trả lời:


482

Nếu bạn muốn áp dụng bộ chọn cho ngữ cảnh được cung cấp bởi một bộ jQuery hiện có, hãy thử hàm find () :

element.find(">:first-child").toggleClass("redClass");

Jørn Schou-Rode lưu ý rằng có lẽ bạn chỉ muốn tìm hậu duệ trực tiếp đầu tiên của thành phần bối cảnh, do đó bộ chọn con (>). Ông cũng chỉ ra rằng bạn cũng có thể sử dụng hàm children () , rất giống với find () nhưng chỉ tìm kiếm một cấp độ sâu trong cấu trúc phân cấp (đó là tất cả những gì bạn cần ...):

element.children(":first").toggleClass("redClass");

1
cảm ơn! hoạt động hoàn hảo. Tôi tưởng tượng những cách khác được liệt kê dưới đây cũng sẽ làm việc.
macca1

6
Tôi tin rằng find()các tìm kiếm thông qua tất cả các hậu duệ và :first-childcó thể phù hợp với một yếu tố cho mỗi phụ huynh. Do đó, truy vấn này có thể trả về một số yếu tố. Hay là tôi nhầm?
Jørn Schou-Rode

19
Tôi biết đây là một câu hỏi / câu trả lời cũ, nhưng việc sử dụng bộ chọn ">" mà không có cha mẹ trong bộ chọn đó bị phản đối (ví dụ: ">: Firstchild") kể từ jQuery 1.8. Tôi đề nghị thay vì sử dụng element.children(":first-child")hoặcelement.children().first();
Kevin B

3
@KevinB rõ ràng họ đã quyết định không từ chối nó sau tất cả
Alnitak

1
cách tiếp cận tốt nhất sẽ KHÔNG lặp lại trên tất cả các mục và sau đó chọn mục đầu tiên, như một số gợi ý ở đây. Đây sẽ là BAD.
vsync


51

Tôi đã thêm thử nghiệm jsperf để xem sự khác biệt về tốc độ cho các cách tiếp cận khác nhau để có được đứa con đầu tiên (tổng số hơn 1000 trẻ em)

được, notif = $('#foo')

Các cách của jQuery:

  1. $(":first-child", notif) - 4.324 ops / giây - nhanh nhất
  2. notif.children(":first") - 653 ops / giây - chậm hơn 85%
  3. notif.children()[0] - 1,416 ops / giây - chậm hơn 67%

Cách bản địa:

  1. JavaScript bản địa ' ele.firstChild- 4.934.323 ops / giây (tất cả các cách tiếp cận trên đều chậm hơn 100% so với firstChild)
  2. Yêu tinh bản địa từ jQery: notif[0].firstChild- 4,913,658 ops / giây

Vì vậy, 3 cách tiếp cận jQuery đầu tiên không được khuyến nghị, ít nhất là đối với trẻ đầu tiên (tôi nghi ngờ đó cũng là trường hợp với nhiều phương pháp khác). Nếu bạn có một đối tượng jQuery và cần có con đầu tiên, thì hãy lấy phần tử DOM gốc từ đối tượng jQuery, sử dụng tham chiếu mảng [0] (được khuyến nghị) hoặc .get(0)sử dụng ele.firstChild. Điều này cho kết quả giống hệt như sử dụng JavaScript thông thường.

tất cả các thử nghiệm được thực hiện trong Chrome Canary build v15.0.854.0


20
Trên thực tế, firstChildsẽ không cho kết quả giống như children()các truy vấn của jQuery hoặc bộ chọn. firstChildsẽ bao gồm các nút văn bản hiếm khi mong muốn. contents()Chức năng của jQuery sẽ bao gồm chúng, nhưng children()sẽ không. Hỗ trợ các trình duyệt mới hơn firstElementChildsẽ cung cấp phần tử con đầu tiên, nhưng IE <9 không hỗ trợ nó. Vì vậy, nếu bạn sử dụng, firstChildbạn phải tìm thủ công nút con không phải văn bản đầu tiên.
Tối đa

1
$(":first-child", notif)nên $(":first", notif)cho hành vi dự kiến. Các cựu sẽ trả lại tất cả con cháu phần tử con đầu tiên.
Drazen Bjelovuk

18
element.children().first();

Tìm tất cả trẻ em và nhận được đầu tiên của họ.


1
Cho đến nay phương pháp đơn giản nhất, và hiệu quả hơn .children(':first').
Gras Double

3
Làm thế nào là nó hiệu quả hơn? Dường như nó có được tất cả trẻ em, sau đó lấy đứa đầu tiên, thay vì chỉ có đứa con đầu tiên.
Anthony McGrath

9

Bạn đã thử chưa

$(":first-child", element).toggleClass("redClass");

Tôi nghĩ rằng bạn muốn đặt yếu tố của bạn làm bối cảnh cho tìm kiếm của bạn. Có thể có một cách tốt hơn để làm điều này mà một số guru jQuery khác sẽ nhảy vào đây và ném ra cho bạn :)


3
điều này sẽ thất bại nếu elementcó cháu lớn
Alnitak

4

Tôi vừa mới viết một plugin sử dụng .firstElementChildnếu có thể và quay lại lặp lại qua từng nút riêng lẻ nếu cần:

(function ($) {
    var useElementChild = ('firstElementChild' in document.createElement('div'));

    $.fn.firstChild = function () {
        return this.map(function() {
            if (useElementChild) {
                return this.firstElementChild;
            } else {
                var node = this.firstChild;
                while (node) {
                    if (node.type === 1) {
                        break;
                    }
                    node = node.nextSibling;
                }
                return node;
            }
        });
    };
})(jQuery);

Nó không nhanh như một giải pháp DOM thuần túy, nhưng trong các thử nghiệm jsperf trong Chrome 24, nó nhanh hơn một vài bậc so với bất kỳ phương thức dựa trên bộ chọn jQuery nào khác.


1
Tôi thích plugin này - nhưng có 2 vấn đề: 1) Tập lệnh plugin không thể được đưa vào phần đầu vì document.bodychưa được khởi tạo, 2) Hiệu suất chỉ tốt hơn nhiều so với các lựa chọn thay thế nếu số lượng nút con rất cao. Chỉ với một vài đứa trẻ (nói dưới 10) thì $('>:first-child',context)nhanh hơn một chút. Chỉ có số lượng trẻ em ảnh hưởng đến hiệu suất, không phải độ sâu.
viết mã

@codefactor điểm hay về document.body- Tôi sẽ xem xét điều đó.
Alnitak

4

bạn có thể sử dụng DOM

$(this).children().first()
// is equivalent to
$(this.firstChild)


1

vui lòng sử dụng nó như thế này, điều đầu tiên đặt tên lớp để gắn thẻ p như "myp"

sau đó sử dụng đoạn mã sau

$(document).ready(function() {
    $(".myp").click(function() {
        $(this).children(":first").toggleClass("classname"); // this will access the span.
    })
})

-3

Nếu bạn muốn có con đầu lòng ngay lập tức bạn cần

    $(element).first();

Nếu bạn muốn phần tử đầu tiên cụ thể trong dom từ phần tử của bạn thì hãy sử dụng bên dưới

    var spanElement = $(elementId).find(".redClass :first");
    $(spanElement).addClass("yourClassHere");

dùng thử: http://jsfiddle.net/vgGbc/2/


11
Điều này là sai - nếu elementlà một nút DOM thì $(element).first()tương đương với $(element), không phải là con đầu tiên của nó.
Alnitak

1
Đồng ý, nếu phần tử là nút DOM $ (phần tử) .first () tương đương $ (phần tử), điều này gây ra sự cố cho tôi với liên kết knockoutJS
drgn
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.