อะไรคือความแตกต่างระหว่าง jQuery .live () และ .on ()


85

ฉันเห็นว่ามีวิธีการใหม่.on()ใน jQuery 1.7 ที่แทนที่.live()ในเวอร์ชันก่อนหน้านี้

ฉันสนใจที่จะทราบความแตกต่างระหว่างวิธีนี้และประโยชน์ของการใช้วิธีใหม่นี้

คำตอบ:


99

ในเอกสารค่อนข้างชัดเจนว่าทำไมคุณไม่ต้องการใช้สด ตามที่เฟลิกซ์กล่าวถึง.onเป็นวิธีการแนบเหตุการณ์ที่มีความคล่องตัวมากขึ้น

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

  • jQuery พยายามดึงข้อมูลองค์ประกอบที่ระบุโดยตัวเลือกก่อนที่จะเรียกใช้.live()เมธอดซึ่งอาจใช้เวลานานในเอกสารขนาดใหญ่
  • ไม่รองรับวิธีการเชื่อมโยง ยกตัวอย่างเช่น$("a").find(".offsite, .external").live( ... ); เป็น ไม่ถูกต้องและไม่สามารถทำงานได้ตามที่คาดไว้
  • เนื่องจาก.live()เหตุการณ์ทั้งหมดถูกแนบไว้ที่documentองค์ประกอบเหตุการณ์จึงใช้เส้นทางที่ยาวที่สุดและช้าที่สุดเท่าที่จะเป็นไปได้ก่อนที่จะจัดการ
  • การโทรevent.stopPropagation() ในตัวจัดการเหตุการณ์ไม่มีประสิทธิภาพในการหยุดตัวจัดการเหตุการณ์ที่แนบมาด้านล่างในเอกสาร documentเหตุการณ์ได้แพร่กระจายไปแล้ว
  • .live()ปฏิสัมพันธ์วิธีด้วยวิธีการอื่น ๆ ที่จัดกิจกรรมในรูปแบบที่สามารถเป็นที่น่าแปลกใจเช่น $(document).unbind("click")ลบทั้งหมดไสคลิกที่แนบมาด้วยการเรียกร้องใด ๆ ที่จะ.live()!

8
แค่สงสัยว่านี่คือจุดที่ทำไมพวกเขาไม่ปรับปรุงวิธีการถ่ายทอดสดแทนที่จะสร้างวิธีการใหม่ เว้นแต่จะมีบางสิ่งบางอย่างที่สามารถทำได้ แต่ทำไม่ได้?
neobie

1
@neobie เพื่อทำให้รหัสของคุณมีความหมายมากขึ้นและมีความสม่ำเสมอ
Om Shankar

@neobie: ฉันคิดว่ามันจะรักษาความเข้ากันได้แบบย้อนกลับ ความแตกต่างที่ระบุในคำตอบนี้แสดงให้เห็นว่าพฤติกรรมของพวกเขาแตกต่างกันเล็กน้อยอย่างไร หากlive()ถูกแก้ไขให้มีลักษณะการทำงานon()อาจทำให้โค้ดที่มีอยู่เสียหายได้ คน jQuery แสดงให้เห็นว่าพวกเขาไม่จำเป็นต้องกลัวที่จะ "ทำลาย" รหัสเดิม แต่ฉันคิดว่าในกรณีนี้พวกเขาตัดสินใจว่าเหมาะสมที่จะไม่เสี่ยงต่อการเกิดการถดถอย
rinogo

ดูเหมือนว่าจะเป็นเช่นนั้น live()เลิกใช้งานใน 1.7 และลบออกใน 1.9 api.jquery.com/live
rinogo

12

ความแตกต่างอย่างหนึ่งที่ผู้คนสะดุดเมื่อย้ายจาก.live()ไปยัง.on()คือพารามิเตอร์สำหรับ.on()จะแตกต่างกันเล็กน้อยเมื่อเชื่อมโยงเหตุการณ์กับองค์ประกอบที่เพิ่มแบบไดนามิกใน DOM

นี่คือตัวอย่างของไวยากรณ์ที่เราเคยใช้กับ.live()วิธีการ:

$('button').live('click', doSomething);

function doSomething() {
    // do something
}

ขณะนี้.live()เลิกใช้งานแล้วใน jQuery เวอร์ชัน 1.7 และถูกลบออกในเวอร์ชัน 1.9 คุณควรใช้.on()วิธีนี้ นี่คือตัวอย่างที่เทียบเท่าโดยใช้.on()วิธีการ:

$(document).on('click', 'button', doSomething);

function doSomething() {
    // do something
}

โปรดทราบว่าเรากำลังเรียก.on()กับเอกสารมากกว่าปุ่มตัวเอง เราระบุตัวเลือกสำหรับองค์ประกอบที่มีเหตุการณ์ที่เรากำลังฟังอยู่ในพารามิเตอร์ที่สอง

ในตัวอย่างด้านบนฉันกำลังเรียก.on()ใช้เอกสาร แต่คุณจะได้รับประสิทธิภาพที่ดีขึ้นหากคุณใช้องค์ประกอบใกล้กับตัวเลือกของคุณมากขึ้น องค์ประกอบบรรพบุรุษใด ๆ .on()ที่จะทำงานตราบเท่าที่มันอยู่บนหน้าเว็บก่อนที่คุณเรียก

สิ่งนี้มีอธิบายไว้ในเอกสารประกอบแต่พลาดได้ง่ายมาก



2
.live()

วิธีนี้ใช้เพื่อแนบตัวจัดการเหตุการณ์สำหรับองค์ประกอบทั้งหมดที่ตรงกับตัวเลือกปัจจุบันในตอนนี้และในอนาคต

$( "#someid" ).live( "click", function() {
  console.log("live event.");
});

และ

.on()

วิธีนี้ใช้เพื่อแนบฟังก์ชันตัวจัดการเหตุการณ์สำหรับเหตุการณ์อย่างน้อยหนึ่งเหตุการณ์เข้ากับองค์ประกอบที่เลือกด้านล่างคือตัวอย่าง

$( "#someid" ).on( "click", function() {
  console.log("on event.");
});

1

บทแนะนำที่ดีเกี่ยวกับความแตกต่างระหว่าง on vs live

อ้างจากลิงค์ด้านบน

มีอะไรผิดปกติกับ. live ()

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

  1. jQuery พยายามดึงข้อมูลองค์ประกอบที่ระบุโดยตัวเลือกก่อนที่จะเรียกใช้เมธอด. live () ซึ่งอาจใช้เวลานานในเอกสารขนาดใหญ่
  2. ไม่รองรับวิธีการเชื่อมโยง ตัวอย่างเช่น $ (“ a”). find (“. offsite, .external”). live (…); ไม่ถูกต้องและไม่ทำงานตามที่คาดไว้
  3. เนื่องจากเหตุการณ์. live () ทั้งหมดถูกแนบที่องค์ประกอบเอกสารเหตุการณ์จึงใช้เส้นทางที่ยาวที่สุดและช้าที่สุดเท่าที่จะเป็นไปได้ก่อนที่จะจัดการ
  4. การเรียก event.stopPropagation () ในตัวจัดการเหตุการณ์ไม่ได้ผลในการหยุดตัวจัดการเหตุการณ์ที่แนบมาด้านล่างในเอกสาร เหตุการณ์ได้แพร่กระจายไปยังเอกสารแล้ว
  5. เมธอด. live () โต้ตอบกับเมธอดเหตุการณ์อื่น ๆ ในรูปแบบที่น่าแปลกใจเช่น $ (document) .unbind (“ click”) จะลบตัวจัดการการคลิกทั้งหมดที่แนบมาจากการเรียกไปที่. live ()!

0

ดูข้อมูลเพิ่มเติมได้ที่ .. . live ()และ. บน ()

.live () ใช้เมธอดเมื่อคุณจัดการกับการสร้างเนื้อหาแบบไดนามิก ... เหมือนกับที่ฉันสร้างขึ้นในโปรแกรมที่เพิ่มแท็บเมื่อฉันเปลี่ยนค่าของ Jquery Slider และฉันต้องการแนบฟังก์ชันปุ่มปิดกับทุกแท็บ ซึ่งจะสร้าง ... รหัสที่ฉันได้ลองคือ ..

var tabs = $('#tabs').tabs();
                                        // live() methos attaches an event handler for all
                                        //elements which matches the curren selector
        $( "#tabs span.ui-icon-close" ).live( "click", function() {


            // fetches the panelId attribute aria-control which is like tab1 or vice versa
            var panelId = $( this  ).closest( "li" ).remove().attr( "aria-controls" );
            $( "#" + panelId ).remove();
            tabs.tabs( "refresh" );
        });

และทำงานได้ดีมาก ...


ยินดีต้อนรับสู่ SO โปรดลองอธิบายรายละเอียดเกี่ยวกับคำตอบของคุณและอย่าให้เพียงแค่ลิงก์เท่านั้นคำตอบแบบลิงก์เท่านั้นถือเป็นการปฏิบัติที่ไม่ดีที่นี่
mata

ขอบคุณ .. ฉันจะเก็บสิ่งนี้ไว้ในใจสำหรับคำตอบในอนาคต .. :)
Hiren

0

ผมผู้เขียนของส่วนขยายของ Chrome "แสดงความคิดเห็นบันทึก"ซึ่งใช้ jQuery .live()และหนึ่งที่นำมาใช้ วิธีการทำงานของส่วนขยายคือการแนบ Listener เข้ากับ textareas ทั้งหมดโดยใช้ live()- สิ่งนี้ทำงานได้ดีเมื่อใดก็ตามที่เอกสารมีการเปลี่ยนแปลงเอกสารจะยังคงแนบผู้ฟังเข้ากับพื้นที่ข้อความใหม่ทั้งหมด

ฉันย้ายไป.on()แต่มันใช้ไม่ได้เช่นกัน มันไม่ได้แนบฟังเมื่อใดก็ตามที่มีการเปลี่ยนแปลงเอกสาร - .live()ดังนั้นฉันได้หวนกลับไปใช้ .on()นั่นคือข้อผิดพลาดผมคิดว่าใน แค่ระวังเรื่องนี้ฉันเดา


10
คุณต้องใช้มันผิด - มันมีไวยากรณ์ที่แตกต่างกันเล็กน้อยกับ.live()วิธีการ เทียบเท่า.on()กับ$('p').live('click', function () { alert('clicked'); });คือ$(document).on('click', 'p', function () { alert('clicked'); });. โปรดทราบว่าคุณใช้.on()เมธอดบนdocumentแล้วระบุองค์ประกอบที่คุณต้องการแนบตัวจัดการเหตุการณ์เพื่อฟังในพารามิเตอร์ที่สอง
ajbeaven

1
คุณสามารถอ่านเพิ่มเติมเกี่ยวกับเรื่องนี้ที่นี่: api.jquery.com/on ดูภายใต้หัวข้อเหตุการณ์โดยตรงและที่ได้รับมอบหมาย
ajbeaven

1
ขอแนะนำให้อ่านบทความนี้ด้วย: elijahmanor.com/2012/02/…
ajbeaven

1
เรายังสามารถทำ $ (selector1). บน (event, selector2, function) โดยที่ selector1 คือ parent และ selector2 เป็นลูกของ selector1 ซึ่งจะช่วยลดพื้นที่การค้นหาเนื่องจากคุณไม่ต้องค้นหาทั้งเอกสาร
Ramsharan

1
@ajbeaven คุณควรเปลี่ยนความคิดเห็นแรกของคุณที่นี่เป็นคำตอบ (นั่นคือสิ่งที่ฉันกำลังมองหาเมื่อมาถึงที่นี่)
atwright147

-1

ฉันมีข้อกำหนดในการระบุเหตุการณ์ปิดของเบราว์เซอร์ หลังจากทำการค้นคว้าแล้วฉันกำลังทำต่อไปนี้โดยใช้ jQuery 1.8.3

  1. เปิดแฟล็กโดยใช้ jQuery ต่อไปนี้เมื่อคลิกไฮเปอร์ลิงก์

    $ ('a'). live ('click', function () {cleanSession = false;});

  2. เปิดแฟล็กโดยใช้ jQuery ต่อไปนี้เมื่อใดก็ตามที่ปุ่มป้อนข้อมูลประเภทของการส่งถูกคลิก

$ ("input [type = submit]"). live ('click', function () {alert ('input button clicked'); cleanSession = false;});

  1. เปิดแฟล็กโดยใช้ jQuery ต่อไปนี้เมื่อใดก็ตามที่ส่งแบบฟอร์มเกิดขึ้น

$ ('form'). live ('submit', function () {cleanSession = false;});

ตอนนี้สิ่งสำคัญ ... วิธีแก้ปัญหาของฉันจะใช้ได้ก็ต่อเมื่อฉันใช้. live แทน. บน. ถ้าฉันใช้. on เหตุการณ์นั้นจะเริ่มทำงานหลังจากที่ส่งแบบฟอร์มและสายเกินไป หลายครั้งที่ส่งแบบฟอร์มของฉันโดยใช้การโทรด้วยจาวาสคริปต์ (document.form.submit)

ดังนั้นจึงมีความแตกต่างที่สำคัญระหว่าง. live และ. on หากคุณใช้. live เหตุการณ์ของคุณจะถูกเริ่มทำงานทันที แต่ถ้าคุณเปลี่ยนไปใช้. จะไม่ถูกยิงตรงเวลา


1
สิ่งนี้ไม่เป็นความจริงคุณต้องใช้.onอย่างไม่ถูกต้องหรืออย่างอื่นในรหัสของคุณทำให้สิ่งนี้เกิดขึ้น อาจวางโค้ดสำหรับ.onวิธีการของคุณ
ajbeaven

ใช่. นี่ไม่เป็นความจริง. .on () เป็น. live () เวอร์ชันที่ปรับปรุงแล้ว วางรหัสของคุณที่นี่ เพื่อที่เราจะได้มีความชัดเจน
RecklessSergio
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.