อะไรคือความแตกต่างระหว่าง "on" กับ "live" หรือ "bind"


172

ใน jQuery v1.7มีการonเพิ่มวิธีการใหม่ จากเอกสาร:

'วิธีการ. on () แนบตัวจัดการเหตุการณ์กับชุดองค์ประกอบที่เลือกในปัจจุบันในวัตถุ jQuery ตั้งแต่ jQuery 1.7 เมธอด. on () จัดเตรียมการทำงานทั้งหมดที่จำเป็นสำหรับการเชื่อมต่อตัวจัดการเหตุการณ์ '

ความแตกต่างกับliveและbindคืออะไร?



มองหาบางอย่างเช่นนั้นก่อนถามและไม่ประสบความสำเร็จ ขอบคุณ!
Diego

คำตอบ:


329

on()เป็นความพยายามที่จะรวมส่วนใหญ่ของฟังก์ชั่นการผูกเหตุการณ์ของ jQuery เป็นหนึ่งเดียว นี้มีโบนัสเพิ่มของการจัดเก็บ up ไร้ประสิทธิภาพที่มีVSlive delegateใน jQuery เวอร์ชันอนาคตวิธีการเหล่านี้จะถูกลบทิ้งonและoneจะถูกทิ้งไว้

ตัวอย่าง:

// Using live()
$(".mySelector").live("click", fn);

// Equivalent `on` (there isn't an exact equivalent, but with good reason)
$(document).on("click", ".mySelector", fn);
// Using bind()
$(".mySelector").bind("click", fn);

// Equivalent `on`
$(".mySelector").on("click", fn);
// Using delegate()
$(document.body).delegate(".mySelector", "click", fn);

// Equivalent `on`
$(document.body).on("click", ".mySelector", fn);

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

bind: function( types, data, fn ) {
    return this.on( types, null, data, fn );
},
live: function( types, data, fn ) {
    jQuery( this.context ).on( types, this.selector, data, fn );
    return this;
},
delegate: function( selector, types, data, fn ) {
    return this.on( types, selector, data, fn );
},

ดูhttps://github.com/jquery/jquery/blob/1.7/src/event.js#L965


@JamWaffles เป็นคำตอบที่เข้าใจง่ายที่สุด คุณช่วยเพิ่มการเปรียบเทียบระหว่างวันที่และวันกับคำตอบเพื่อทำคำตอบให้สำเร็จได้ไหม ขอบคุณ!
Diego

lols คุณเพิ่ม jquery source 4 วินาทีต่อหน้าฉัน: D btw live
text

1
คุณอาจต้องการอ้างถึงแท็ก 1.7 แทนมิฉะนั้นการเปลี่ยนแปลงในอนาคตอาจทำให้ลิงก์ของคุณไม่ถูกต้อง (ไม่ได้ชี้ไปที่ตำแหน่งที่ถูกต้อง): github.com/jquery/jquery/blob/1.7/src/event.js#L965
Felix Kling

3
$(document.body).delegate("click", ".mySelector", fn);ควรเป็น$(document.body).delegate(".mySelector", "click", fn);
Sonny

2
@dsdsdsdsd ปิดทำหน้าที่เป็นตัวแทนทั่วไปสำหรับ unbind, unlive และ undelegate
Andy E

12

ondelegateอยู่ในลักษณะที่ใกล้เคียงกับ เหตุใดจึงไม่ใช้ตัวแทน เป็นเพราะonไม่ได้มาคนเดียว มีoffเพื่อยกเลิกการผูกเหตุการณ์และoneสร้างเหตุการณ์ที่จะดำเนินการเพียงครั้งเดียวเท่านั้น นี่เป็น "แพ็คเกจ" ของกิจกรรมใหม่

ปัญหาหลักliveคือว่ามันแนบกับ "หน้าต่าง" บังคับให้คลิกเหตุการณ์ (หรือเหตุการณ์อื่น ๆ ) ในองค์ประกอบลึกลงไปในโครงสร้างหน้า (โดม) เพื่อ "ฟองขึ้น" ไปด้านบนของหน้าเพื่อค้นหาเหตุการณ์ ผู้จัดการยินดีที่จะจัดการกับมัน ในแต่ละระดับต้องมีการตรวจสอบตัวจัดการเหตุการณ์ทั้งหมดซึ่งจะเพิ่มขึ้นอย่างรวดเร็วหากคุณทำการฝังลึก ( <body><div><div><div><div><table><table><tbody><tr><td><div><div><div><ul><li><button> etc etc etc...)

ดังนั้นbindเช่นเดียวกับclickเช่นตัวประสานกิจกรรมทางลัดอื่น ๆ แนบโดยตรงกับเป้าหมายเหตุการณ์ หากคุณมีตารางสมมุติ 1,000 บรรทัดและ 100 คอลัมน์และแต่ละเซลล์ 100'000 มีช่องทำเครื่องหมายที่คลิกที่คุณต้องการจัดการ แนบ 100'000 จัดการเหตุการณ์จะใช้เวลามากของเวลาในการโหลดหน้า การสร้างเหตุการณ์เดียวที่ระดับโต๊ะและการใช้การมอบหมายเหตุการณ์นั้นมีหลายลำดับความสำคัญที่มีประสิทธิภาพมากกว่า เป้าหมายของเหตุการณ์จะถูกดึงขึ้นมาในเวลาดำเนินการกิจกรรม " this" จะเป็นตาราง แต่ " event.target" จะthisเป็นclickฟังก์ชั่นปกติของคุณ " " ตอนนี้สิ่งที่ดีonคือ " this" จะเป็นเป้าหมายของเหตุการณ์เสมอไม่ใช่คอนเทนเนอร์ที่เชื่อมต่ออยู่


ผู้รับมอบสิทธิ์ไม่ได้มาพร้อมกับผู้ได้รับมอบหมายหรือไม่
DaveWalley

1
ได้. จุดดี คุณเรียนรู้ทุกวัน;) (หมอมีการปรับปรุงอย่างมากตั้งแต่ 2011 เจ้า)
roselan

5

ด้วย.onวิธีการที่มันเป็นไปได้ที่จะทำ.live, .delegateและ.bindมีฟังก์ชั่นเหมือนกัน แต่มี.live()เพียง.live()(เหตุการณ์มอบหมายเอกสาร) จะเป็นไปได้

jQuery("#example").bind( "click", fn ) = jQuery( "#example").on( "click", fn );

jQuery("#example").delegate( ".examples", "click", fn ) = jQuery( "#example" ).on( "click", ".examples", fn )

jQuery("#example").live( fn ) = jQuery( document ).on( "click", "#example", fn )

ฉันสามารถยืนยันได้โดยตรงจากแหล่ง jQuery:

bind: function( types, data, fn ) {
    return this.on( types, null, data, fn );
},

live: function( types, data, fn ) {
    jQuery( this.context ).on( types, this.selector, data, fn );
    return this;
},

delegate: function( selector, types, data, fn ) {
    return this.on( types, selector, data, fn );
},

jQuery (this.context)? this.context=== documentในกรณีส่วนใหญ่


3

(ประโยคเปิดของฉันมีเหตุผลมากกว่านี้ก่อนที่คุณจะเปลี่ยนคำถามในขั้นต้นคุณต้องพูดว่า "ต่างกันliveอย่างไร")

onมันเป็นมากกว่าแบบที่delegateเป็นliveพื้นมันเป็นรูปแบบที่รวมเป็นหนึ่งbindและdelegate(ในความเป็นจริงทีมกล่าวว่าจุดประสงค์ของมันคือ"... เพื่อรวมวิธีต่างๆทั้งหมดของการแนบเหตุการณ์เข้ากับเอกสาร ... " )

liveเป็นพื้นon(หรือdelegate) ที่แนบมากับเอกสารโดยรวม มันเลิกใช้เมื่อ v1.7ในความโปรดปรานของการใช้หรือon delegateไปข้างหน้าฉันสงสัยว่าเราจะเห็นรหัสโดยใช้onเพียงอย่างเดียวแทนที่จะใช้bindหรือdelegate(หรือlive) ...

ดังนั้นในทางปฏิบัติคุณสามารถ:

  1. ใช้onเช่นbind:

    /* Old: */ $(".foo").bind("click", handler);
    /* New: */ $(".foo").on("click", handler);
  2. ใช้onlike delegate(การมอบหมายกิจกรรมที่รูทในองค์ประกอบที่กำหนด):

    /* Old: */ $("#container").delegate(".foo", "click", handler);
    /* New: */ $("#container").on("click", ".foo", handler);
  3. ใช้onlike live(การมอบหมายกิจกรรมที่รูทในเอกสาร):

    /* Old: */ $(".foo").live("click", handler);
    /* New: */ $(document).on("click", ".foo", handler);

1
ในหน้าฉันเชื่อมโยงพูดว่า "ถ้า HTML ใหม่ถูกแทรกลงในหน้าให้เลือกองค์ประกอบและแนบตัวจัดการเหตุการณ์หลังจากที่วาง HTML ใหม่ลงในหน้าหรือใช้เหตุการณ์ที่ได้รับมอบหมายเพื่อแนบตัวจัดการเหตุการณ์ดังที่อธิบายไว้ต่อไป" . ดังนั้นจึงมีแนวโน้มที่จะผูกไม่อยู่ ฉันถูกไหม?
Diego

@Diego: onคือการรวมกันของbindและdelegateและอย่างที่ฉันพูดไม่ชอบliveมาก คุณสามารถใช้onlike bind(แนบ handler โดยตรงกับองค์ประกอบ) หรือคุณสามารถใช้onlike delegate(แนบ handler เข้ากับองค์ประกอบ แต่เริ่มเหตุการณ์เฉพาะเมื่อองค์ประกอบที่แท้จริงคลิกตรงกับตัวเลือกและราวกับว่าองค์ประกอบนั้นเป็น เหตุการณ์ที่เกิดขึ้นใน - เช่นการมอบหมายเหตุการณ์) หรือคุณสามารถใช้มันเหมือนlive( delegateใช้เอกสารเป็นราก) นี่คือการมอบหมายกิจกรรมที่มีประโยชน์หากคุณเพิ่มองค์ประกอบแบบไดนามิก
TJ Crowder

1
การแสดงสดแบบเก่าสามารถใช้เป็นตัวแทนได้$("#id", ".class").live(fn)= = $(".class").delegate("#id", fn );จริงๆแล้วในแหล่งข้อมูลเก่า jQuery ที่พวกเขาใช้การถ่ายทอดสดเป็นกรณีทั่วไปและผู้แทนเป็นกรณีพิเศษซึ่งทำให้สิ่งนี้สับสนมากขึ้นเมื่อคุณคิดถึงมัน
Esailija

@Esailija: ยุติธรรมเพียงพอ ฉันไม่คิดว่ามันเป็นที่รู้จักกันดีในการใช้เพราะพวกเขาเพิ่มdelegateอย่างรวดเร็ว แต่ก็ยัง :-)
TJ Crowder


2

ไม่มีหนึ่งสำหรับกรณีการใช้งานขั้นพื้นฐาน สองบรรทัดนี้เหมือนกันตามหน้าที่

$( '#element' ).bind( 'click', handler );
$( '#element' ).on( 'click', handler );

.on () สามารถทำการมอบหมายกิจกรรมและเป็นที่ต้องการ

.bind () เป็นเพียงนามแฝงสำหรับ. on () ทันที นี่คือนิยามของฟังก์ชัน bind ใน 1.7.1

bind: function( types, data, fn ) {
return this.on( types, null, data, fn );
},

แนวคิดสำหรับการเพิ่ม. on () คือการสร้าง API เหตุการณ์แบบครบวงจรแทนที่จะมีหลายฟังก์ชันสำหรับการผูกเหตุการณ์ .on () แทนที่. ผูก (), .live () และ .delegate ()


0

สิ่งที่คุณควรระวังหากคุณต้องการให้ตัวจัดการเหตุการณ์เชื่อมโยงกับองค์ประกอบ - ใส่ใจองค์ประกอบที่ตัวจัดการติดอยู่!

ตัวอย่างเช่นถ้าคุณใช้:

$('.mySelector').bind('click', fn);

คุณจะได้รับตัวจัดการเหตุการณ์โดยใช้:

$('.mySelector').data('events');

แต่ถ้าคุณใช้:

$('body').on('click', '.mySelector', fn);

คุณจะได้รับตัวจัดการเหตุการณ์โดยใช้:

$('body').data('events');

(ในกรณีสุดท้ายวัตถุเหตุการณ์ที่เกี่ยวข้องจะมีตัวเลือก = ". mySelector")


eventsไม่มีเอกสารและฉันคิดว่ามันใช้งานไม่ได้ใน 1.9
John Dvorak

ขวา. หนึ่งสามารถใช้ _data แทนข้อมูลในรุ่นที่ใหม่กว่า คำตอบคือเกี่ยวกับความแตกต่างใน "เจ้าของเหตุการณ์" แทนที่จะเป็นไวยากรณ์ที่แน่นอนสำหรับรุ่นเก่าหรือใหม่ มีโพสต์อื่น ๆ เกี่ยวกับไวยากรณ์ที่แน่นอนสำหรับรุ่น JQuery ที่แตกต่างกัน ตัวอย่างเช่นstackoverflow.com/questions/2518421/ …
Alexander
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.