jQuery ลูกคนแรกของ“ นี่”


317

ฉันพยายามส่ง "สิ่งนี้" จากช่วงการคลิกไปยังฟังก์ชัน jQuery ที่สามารถเรียกใช้ jQuery กับลูกคนแรกขององค์ประกอบที่ถูกคลิกนั้นได้ ดูเหมือนจะไม่ถูกต้อง ...

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

javascript:

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

ฉันจะอ้างอิงถึง: ลูกคนแรกขององค์ประกอบได้อย่างไร


4
หากคุณใช้ jQuery ทำไมคุณไม่ผูกตัวจัดการเหตุการณ์ด้วย jQuery?
Vivin Paliath

2
เนื่องจากตัวจัดการเหตุการณ์ผูกจะต้องเริ่มต้นใน document.ready () ซึ่งเพิ่มประสิทธิภาพการทำงาน (นี่คือแอปสำหรับ IE6) หรือมีวิธีอื่นหรือไม่
macca1

อืม .. ไม่แน่ใจ การผูกโดยใช้ jQuery เป็นวิธีมาตรฐาน (หากคุณใช้ jQuery อยู่แล้ว) ชนิดของการตีประสิทธิภาพคุณพบเมื่อคุณใช้jQuery(document).ready(...)?
Vivin Paliath

มันเป็นแอพพลิเคชั่นขนาดใหญ่ที่มีนักพัฒนา 7+ คน เดิมทีมันเป็น 4+ วินาทีก่อนที่ฉันจะพยายามทำความสะอาด ดังนั้นฉันจึงควรหลีกเลี่ยงการเพิ่มมากขึ้นเมื่อฉันไม่จำเป็นต้อง :)
macca1

คำตอบ:


482

หากคุณต้องการใช้ตัวเลือกกับบริบทที่กำหนดโดยชุด jQuery ที่มีอยู่ให้ลองใช้ฟังก์ชัน find () :

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

Jørn Schou-Rode ตั้งข้อสังเกตว่าคุณอาจต้องการค้นหาผู้สืบทอดโดยตรงคนแรกขององค์ประกอบบริบทเท่านั้นดังนั้นตัวเลือกลูก (>) นอกจากนี้เขายังชี้ให้เห็นว่าคุณสามารถใช้ฟังก์ชัน children ()ซึ่งคล้ายกับ find () แต่ค้นหาได้ลึกเพียงระดับเดียวในลำดับชั้น (ซึ่งเป็นสิ่งที่คุณต้องการ ... ):

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

1
ขอบคุณ! ทำงานได้อย่างสมบูรณ์แบบ ฉันคิดว่าวิธีอื่น ๆ ที่ระบุไว้ด้านล่างจะใช้ได้เช่นกัน
macca1

6
ฉันเชื่อว่าfind()การค้นหาผ่านผู้สืบทอดทั้งหมดและ:first-childสามารถจับคู่หนึ่งองค์ประกอบต่อผู้ปกครอง ดังนั้นเคียวรีนี้อาจส่งคืนองค์ประกอบหลายอย่าง หรือฉันเข้าใจผิด?
Jørn Schou-Rode

19
ฉันรู้ว่านี่เป็นคำถาม / คำตอบเก่า แต่การใช้ตัวเลือก ">" ที่ไม่มีผู้ปกครองในตัวเลือกนั้นจะถูกคิดค่าเสื่อมราคา (ตัวอย่างเช่น ">: firstchild") ณ jQuery 1.8 ฉันขอแนะนำให้ใช้แทนelement.children(":first-child")หรือelement.children().first();
เควิน B

3
@KevinB เห็นได้ชัดว่าพวกเขาตัดสินใจที่จะไม่คัดค้านหลังจากทั้งหมด
Alnitak

1
วิธีที่ดีที่สุดคือไม่วนซ้ำในทุกไอเท็มจากนั้นเลือกอันแรกตามที่แนะนำ นี่จะเป็นสิ่งที่ไม่ดี
vsync


51

ฉันได้เพิ่มการทดสอบjsperfเพื่อดูความแตกต่างความเร็วสำหรับวิธีการต่าง ๆ เพื่อรับลูกคนแรก (รวม 1,000+ เด็ก)

ได้รับ notif = $('#foo')

วิธี jQuery:

  1. $(":first-child", notif) - 4,304 ops / วินาที - เร็วที่สุด
  2. notif.children(":first") - 653 ops / วินาที - ช้าลง 85%
  3. notif.children()[0] - 1,416 ops / วินาที - ช้าลง 67%

วิธีพื้นเมือง:

  1. JavaScript ดั้งเดิม ' ele.firstChild- 4,934,323 ops / วินาที (วิธีการทั้งหมดข้างต้นช้ากว่า 100% เมื่อเทียบกับfirstChild)
  2. Native DOM ele จาก jQery: notif[0].firstChild- 4,913,658 ops / วินาที

ดังนั้นไม่แนะนำ 3 jQuery วิธีแรกอย่างน้อยสำหรับลูกคนแรก (ฉันสงสัยว่าจะเป็นเช่นนี้กับคนอื่น ๆ ด้วย) หากคุณมีวัตถุ jQuery และความต้องการที่จะได้รับเป็นครั้งแรกที่เด็กแล้วได้รับองค์ประกอบ DOM พื้นเมืองจากวัตถุ jQuery ใช้อ้างอิงอาร์เรย์[0] (แนะนำ)หรือและใช้.get(0) ele.firstChildสิ่งนี้ให้ผลลัพธ์ที่เหมือนกันเหมือนกับการใช้งาน JavaScript ปกติ

การทดสอบทั้งหมดเสร็จสิ้นใน Chrome Canary build v15.0.854.0


20
ที่จริงแล้วfirstChildจะไม่ให้ผลลัพธ์เหมือนกับchildren()แบบสอบถามของ jQuery หรือตัวเลือก firstChildจะรวมถึงโหนดข้อความที่ไม่ค่อยต้องการ contents()ฟังก์ชั่นของ jQuery จะ รวมไว้ด้วย แต่children()จะไม่รวม เบราว์เซอร์ที่ใหม่กว่ารองรับfirstElementChildซึ่งจะให้องค์ประกอบลูกแรก แต่ IE <9 ไม่รองรับ ดังนั้นถ้าคุณใช้firstChildคุณจะต้องค้นหาโหนดชายด์ที่ไม่ใช่ข้อความแรกด้วยตนเอง
สูงสุด

1
$(":first-child", notif)ควร$(":first", notif)สำหรับพฤติกรรมที่คาดหวัง อดีตจะส่งกลับลูกหลานองค์ประกอบลูกคนแรกทั้งหมด
Drazen Bjelovuk

18
element.children().first();

ค้นหาเด็กทุกคนและเป็นคนแรกของพวกเขา


1
.children(':first')ไกลโดยวิธีที่ง่ายและมีประสิทธิภาพมากกว่า
Gras Double

3
มันมีประสิทธิภาพมากกว่านี้อย่างไร? ดูเหมือนว่าจะทำให้เด็กทุกคนจากนั้นนำลูกคนแรกมาเทียบกับรับลูกคนแรก
แอนโธนี McGrath

9

คุณเคยลองไหม

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

ฉันคิดว่าคุณต้องการกำหนดองค์ประกอบของคุณเป็นบริบทสำหรับการค้นหาของคุณ อาจมีวิธีที่ดีกว่าในการทำสิ่งนี้ซึ่งปราชญ์ jQuery อื่น ๆ จะกระโดดเข้ามาที่นี่และโยนคุณออกไป :)


3
สิ่งนี้จะล้มเหลวหากelementมีลูกหลาน
Alnitak

4

ฉันเพิ่งเขียนปลั๊กอินที่ใช้.firstElementChildถ้าเป็นไปได้และย้อนกลับไปทำซ้ำในแต่ละโหนดถ้าจำเป็น:

(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);

มันไม่เร็วเท่าโซลูชัน DOM บริสุทธิ์ แต่ในการทดสอบ jsperfภายใต้ Chrome 24 มันเป็นคำสั่งที่มีขนาดเร็วกว่าวิธีการเลือก jQuery อื่น ๆ


1
ฉันชอบปลั๊กอินนี้ - แต่มี 2 ประเด็น: 1) สคริปต์ปลั๊กอินไม่สามารถรวมอยู่ในส่วนหัวได้เนื่องจากdocument.bodyยังไม่เริ่มต้น 2) ประสิทธิภาพจะดีกว่าทางเลือกหากจำนวนโหนดโหนดสูงมาก สำหรับเด็กเพียงไม่กี่คน (พูดน้อยกว่า 10) $('>:first-child',context)เร็วกว่านิดหน่อย เฉพาะจำนวนของเด็กที่มีผลต่อประสิทธิภาพไม่ใช่ความลึก
codefactor

@ codefactor จุดที่ดีเกี่ยวกับdocument.body- ฉันจะดูว่า
Alnitak



1

โปรดใช้มันเหมือนสิ่งแรกนี้ตั้งชื่อคลาสให้แท็ก p เช่น "myp"

จากนั้นใช้รหัสต่อไปนี้

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

-3

หากคุณต้องการลูกคนแรกทันทีที่คุณต้องการ

    $(element).first();

หากคุณต้องการองค์ประกอบแรกโดยเฉพาะจากองค์ประกอบของคุณให้ใช้ด้านล่าง

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

ลองใช้: http://jsfiddle.net/vgGbc/2/


11
นี่เป็นเพียงความผิด - หากelementเป็นโหนด DOM ก็$(element).first()จะเทียบเท่า$(element)ได้ไม่ใช่ลูกแรกของมัน
Alnitak

1
เห็นด้วยถ้าองค์ประกอบเป็นโหนด DOM $ (องค์ประกอบ) .first () เท่ากับ $ (องค์ประกอบ) สิ่งนี้ทำให้ฉันมีปัญหากับ knockoutJS binding
drgn
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.