ความแตกต่างระหว่าง. on ('คลิก') เทียบกับ. คลิก ()


526

มีความแตกต่างระหว่างรหัสต่อไปนี้หรือไม่?

$('#whatever').on('click', function() {
     /* your code here */
});

และ

$('#whatever').click(function() {
     /* your code here */
});

คำตอบ:


761

ฉันคิดว่าความแตกต่างอยู่ในรูปแบบการใช้งาน

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

พิจารณา html ต่อไปนี้:

<html>
    <button id="add">Add new</button>
    <div id="container">
        <button class="alert">alert!</button>
    </div>
</html>

เราจะเพิ่มปุ่มใหม่ผ่านทางไหน

$("button#add").click(function() {
    var html = "<button class='alert'>Alert!</button>";
    $("button.alert:last").parent().append(html);
});

และต้องการ "แจ้งเตือน!" เพื่อแสดงการแจ้งเตือน เราสามารถใช้ "คลิก" หรือ "เปิด" สำหรับสิ่งนั้น


เมื่อเราใช้ click

$("button.alert").click(function() {
    alert(1);
});

ด้วยข้างต้นตัวจัดการแยกต่างหากจะถูกสร้างขึ้นสำหรับทุกองค์ประกอบเดียวที่ตรงกับตัวเลือก นั่นหมายความว่า

  1. องค์ประกอบที่ตรงกันจำนวนมากจะสร้างตัวจัดการที่เหมือนกันจำนวนมากและเพิ่มการใช้หน่วยความจำ
  2. รายการที่เพิ่มแบบไดนามิกจะไม่มีตัวจัดการ - เช่นใน html ด้านบนจะมี "Alert!" ที่เพิ่มเข้ามาใหม่ ปุ่มจะไม่ทำงานจนกว่าคุณจะเริ่มต้นตัวจัดการใหม่

เมื่อเราใช้ .on

$("div#container").on('click', 'button.alert', function() {
    alert(1);
});

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


... เหตุผลอื่นที่จะใช้ .on

ดังที่เอเดรียนได้แสดงความคิดเห็นไว้ด้านล่างเหตุผลอีกประการที่ใช้.onคือเหตุการณ์ที่กำหนดเนมสเป

หากคุณเพิ่มตัวจัดการกับ.on("click", handler)คุณโดยปกติแล้วจะลบด้วย.off("click", handler)ซึ่งจะลบตัวจัดการที่มาก เห็นได้ชัดว่ามันใช้งานได้เฉพาะในกรณีที่คุณมีการอ้างอิงถึงฟังก์ชั่นดังนั้นถ้าคุณไม่ได้? คุณใช้เนมสเปซ:

$("#element").on("click.someNamespace", function() { console.log("anonymous!"); });

ด้วยการไม่ผูกพันผ่าน

$("#element").off("click.someNamespace");

2
เกี่ยวกับ: $ ('button.alert'). on ('คลิก', function () {alert (1);}); ?
Matthew

8
@ andreister: แก้ไขให้ถูกต้องหากฉันผิด แต่ฉันเชื่อว่าข้อดีอีกอย่างคือการใช้ namespaces เมื่อใช้on('click' ...)ดูที่stackoverflow.com/a/3973060/759452เช่น on('click.darkenallothersections' ...)และในขณะเดียวกันก็มีon('click.displaynextstep' ...)แล้วฉันสามารถผูกเพียงคนเดียวที่ฉันเลือกใช้.unbind('click.displaynextstep')
Adrien เป็น

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

7
ทุกคนสามารถอธิบายได้ไหมว่าเหตุใด. จึงสามารถทำงานกับรายการที่เพิ่มแบบไดนามิก แต่คลิกไม่ได้
MengT

2
on()เป็นแนวโน้มใน jQuery ฉันต้องอัปเดต$(window).load(function() {});เป็น$(window).on("load", function (e) {})เมื่อฉันอัปเกรดเป็น jQuery 3
Victor Stoddard

37

มีความแตกต่างระหว่างรหัสต่อไปนี้หรือไม่?

ไม่ไม่มีความแตกต่างในการทำงานระหว่างตัวอย่างโค้ดทั้งสองในคำถามของคุณ .click(fn)เป็นวิธีการ "ทางลัด" .on("click", fn)สำหรับ จากเอกสารสำหรับ.on() :

มีวิธีการจดชวเลขสำหรับบางเหตุการณ์เช่น.click()ที่สามารถใช้เพื่อแนบหรือทริกเกอร์ตัวจัดการเหตุการณ์ สำหรับรายการที่สมบูรณ์ของวิธีการจดชวเลขให้ดูที่หมวดหมู่เหตุการณ์

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


4
สิ่งที่เกี่ยวกับปัญหาด้านประสิทธิภาพชี้ให้เห็น @andreister ของฉัน?
rubo77

@ rubo77 เล็กน้อยที่สุด เรากำลังใช้เวลาหนึ่งมิลลิวินาทีในการร่าง
Rory McCrossan

1
@RoryMcCrossan นั่นเป็นเรื่องใหญ่สำหรับฉัน - ฉันกำลังมองหาสิ่งนี้เพราะฉันมีคำถามมากถึง 3000 คำถามบนหน้าเว็บที่ต้องการกิจกรรม หนึ่ง milisec แต่ละรายการทำให้หน้าของฉันใช้เวลาในการดำเนินการนานกว่า 3 วินาที ความคิดเห็นของคุณไม่เป็นประโยชน์สำหรับรายการใหญ่ ๆ
แรนดี้

11
ปัญหาที่ใหญ่กว่าคือสาเหตุที่คุณมีคำถาม 3000 ข้อบนหน้าเว็บ หากคุณทำตามรูปแบบ UI ที่ดีคุณไม่ควรมีข้อมูลมากมายบนหน้าเว็บ ดูเป็นการเพจหรือการโหลดที่ขี้เกียจ แม้แต่การใช้การมอบหมายเหตุการณ์เพื่อให้มีตัวจัดการเหตุการณ์เดียวสำหรับองค์ประกอบเหล่านั้นจะดีขึ้น
Rory McCrossan

5
@ rubo77 - การเพิ่มประสิทธิภาพจะเห็นได้เฉพาะเมื่อใช้การมอบหมายเหตุการณ์โดยส่งselectorพารามิเตอร์ ถ้าคุณโทร.on()ได้โดยไม่ต้องพารามิเตอร์ไม่มีการปรับปรุงประสิทธิภาพมากกว่าการใช้selector .click()
gilly3

23

.on()เป็นวิธีที่แนะนำในการทำกิจกรรมทั้งหมดที่มีผลผูกพัน ณ jQuery 1.7 มันม้วนฟังก์ชั่นทั้งหมดของทั้งสอง.bind()และ.live()เป็นฟังก์ชั่นเดียวที่เปลี่ยนพฤติกรรมในขณะที่คุณผ่านพารามิเตอร์ที่แตกต่าง

เมื่อคุณเขียนตัวอย่างแล้วไม่มีความแตกต่างระหว่างสองตัวอย่าง ทั้งสองผูกจัดการกับกรณีของclick มอบความยืดหยุ่นเพิ่มเติมในการอนุญาตให้คุณมอบหมายกิจกรรมที่เด็ก ๆ ใช้ไปยังฟังก์ชั่นจัดการเดี่ยวหากคุณเลือก#whateveron()#whatever

// Bind to all links inside #whatever, even new ones created later.
$('#whatever').on('click', 'a', function() { ... });

"ผูกเข้ากับลิงก์ทั้งหมดภายใน #whever แม้กระทั่งสร้างใหม่ในภายหลัง" นั่นไม่ใช่สิ่งที่แน่นอน.live()หรือ นอกจากนี้ดูเหมือนว่าจะขัดแย้งกับคำตอบอื่น ๆ ที่บอกว่ามันมีฟังก์ชั่นการใช้งานเพียงอย่างเดียวเท่านั้น.click()ดังนั้นจึงไม่มีผลกับกิจกรรมในอนาคต
bgcode

3
@babonk - นี้ไม่ได้ขัดแย้งกับคำตอบอื่น ๆ เพราะเป็น Interrobang กล่าวในวรรคแรก.on()สามารถทำสิ่งที่.click()ไม่และทำในสิ่งที่.bind()และ.live()ทำ - มันขึ้นอยู่กับสิ่งที่พารามิเตอร์ที่คุณเรียกมันด้วย (คำตอบอื่น ๆ ที่กล่าวถึงนี้ด้วย) โปรดทราบว่า "การเชื่อมโยงไปยังลิงก์ทั้งหมดภายใน #whething" ไม่ใช่สิ่งที่.live()ทำ แต่เป็นสิ่งที่.delegate()ทำ .live()ผูกกับภายในทั้งหมดdocumentแทนที่จะให้คุณระบุคอนเทนเนอร์ หมายเหตุยัง.live()ถูกคัดค้านจาก jQuery 1.7 เป็นต้นไป
nnnnnn

+1 สำหรับกิจกรรมที่ได้รับมอบหมาย: "โดยการเลือกองค์ประกอบที่รับประกันว่าจะปรากฏในเวลาที่มีการแนบตัวจัดการเหตุการณ์ที่ได้รับมอบหมายคุณสามารถใช้เหตุการณ์ที่ได้รับมอบหมายเพื่อหลีกเลี่ยงความต้องการแนบและลบตัวจัดการเหตุการณ์ได้บ่อย" api.jquery.com/on
jimasp

19

ตามที่กล่าวถึงโดยคำตอบอื่น ๆ :

$("#whatever").click(function(){ });
// is just a shortcut for
$("#whatever").on("click", function(){ })

สังเกตว่าที่.on()สนับสนุนการรวมพารามิเตอร์อื่น ๆ ที่.click()ไม่อนุญาตให้จัดการการมอบหมายเหตุการณ์ (superceding .delegate()และ.live())

(และเห็นได้ชัดว่ามีวิธีลัดอื่น ๆ ที่คล้ายกันสำหรับ "keyup", "focus" ฯลฯ )

เหตุผลที่ฉันโพสต์คำตอบเพิ่มเติมคือการพูดถึงสิ่งที่เกิดขึ้นหากคุณโทร.click()โดยไม่มีพารามิเตอร์:

$("#whatever").click();
// is a shortcut for
$("#whatever").trigger("click");

สังเกตว่าถ้าคุณใช้.trigger()โดยตรงคุณยังสามารถส่งผ่านพารามิเตอร์พิเศษหรือวัตถุเหตุการณ์ jQuery .click()ซึ่งคุณจะไม่สามารถทำอะไรกับ

ฉันยังอยากจะพูดถึงว่าหากดูรหัสที่มา jQuery (ใน jQuery-1.7.1.js) คุณจะเห็นว่าภายใน.click()(หรือ.keyup()อื่น ๆ ) ฟังก์ชั่นที่จริงจะเรียกหรือ.on() .trigger()เห็นได้ชัดว่านี่หมายความว่าคุณสามารถมั่นใจได้ว่าพวกเขามีผลเหมือนกัน แต่ก็หมายความว่าการใช้.click()มีค่าใช้จ่ายเพิ่มเติมเล็กน้อย - ไม่ต้องกังวลหรือคิดในสถานการณ์ส่วนใหญ่ แต่ในทางทฤษฎีมันอาจมีความสำคัญในสถานการณ์พิเศษ

แก้ไข: สุดท้ายโปรดทราบว่า.on()ช่วยให้คุณสามารถผูกหลายเหตุการณ์ในฟังก์ชั่นเดียวกันในหนึ่งบรรทัดเช่น:

$("#whatever").on("click keypress focus", function(){});

วิธีการทั้งสองโหลดในหน่วยความจำที่จะใช้ไม่ใช่หรือ ดังนั้นมันไม่สำคัญหรอก และสำหรับการอ่านมันอาจจะเป็น handier?
Vince V.

@VinceV - ใช่ สำหรับตัวจัดการเหตุการณ์ที่ไม่ได้รับมอบหมาย "มาตรฐาน" ทั้งสองวิธีจะทำสิ่งเดียวกันและความแตกต่างด้านประสิทธิภาพเป็นสิ่งที่ละเลยดังนั้นวิธีการที่คุณใช้นั้นเป็นเรื่องของการตั้งค่าส่วนตัว (ฉันมักจะเลือก.click().)
nnnnnn

9

ไม่ไม่มี
จุดสำคัญon()คือโอเวอร์โหลดอื่น ๆ และความสามารถในการจัดการเหตุการณ์ที่ไม่มีวิธีลัด


1
@ arigold: นี่เป็นโอเวอร์โหลดอื่น ๆ
SLaks

9

เอกสารเหล่านี้ดูเหมือนจะเหมือนกัน ... เอกสารจากฟังก์ชันclick () :

วิธีนี้เป็นทางลัดสำหรับ. ผูก ('คลิก' ตัวจัดการ)

เอกสารจากฟังก์ชั่นเปิด () :

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


มุมมองของคุณทั้งสองควรถูกรวมเข้าด้วยกัน Click () เป็นทางลัดสำหรับ. ผูก () และ. On () ... ตาม JQUERY 1.7.0 + เป็นทางลัดสำหรับ Trigger ('คลิก') ด้วย [ api.jquery.com/click/]
Dhanasekar

นี่เป็นคำอธิบายที่ค่อนข้างตรงไปตรงมาจากเอกสาร แต่คำตอบด้านล่างมีตัวอย่างที่ดีว่าทำไมคนหนึ่งถึงดีกว่าคนอื่นใน.clickvs.on
phatskat

@phatskat - ฉันเห็นด้วยกับคุณ :)
dana

8

.click เหตุการณ์จะใช้งานได้ก็ต่อเมื่ออิลิเมนต์เริ่มแสดงผลและเชื่อมต่อกับองค์ประกอบที่โหลดเมื่อ DOM พร้อมเท่านั้น

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


5

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

$('.clickHere').click(function(){ 
     // this is flat click. this event will be attatched 
     //to element if element is available in 
     //dom at the time when JS loaded. 

  // do your stuff
});

$('.clickHere').on('click', function(){ 
    // same as first one

    // do your stuff
})

$(document).on('click', '.clickHere', function(){
          // this is diffrent type 
          //  of click. The click will be registered on document when JS 
          //  loaded and will delegate to the '.clickHere ' element. This is 
          //  called event delegation 
   // do your stuff
});

$('body').on('click', '.clickHere', function(){
   // This is same as 3rd 
   // point. Here we used body instead of document/

   // do your stuff
});

$('.clickHere').off().on('click', function(){ // 
    // deregister event listener if any and register the event again. This 
    // prevents the duplicate event resistration on same element. 
    // do your stuff
})

3

ตอนนี้พวกเขาเลิกใช้การคลิก () ดังนั้นควรไปด้วย ('คลิก')


ดังนั้นคุณจะทำอย่างไรถ้าคุณต้องการพฤติกรรมการคลิก () เก่าตอนนี้
bgcode

1

เท่าที่ได้รับรู้จากอินเทอร์เน็ตและเพื่อนบางคน. on () จะถูกใช้เมื่อคุณเพิ่มองค์ประกอบแบบไดนามิก แต่เมื่อฉันใช้ในหน้าเข้าสู่ระบบที่เรียบง่ายที่เหตุการณ์การคลิกควรส่ง AJAX ไปที่ node.js และเมื่อกลับมาผนวกองค์ประกอบใหม่มันเริ่มที่จะเรียกการโทรแบบ Multi-AJAX เมื่อฉันเปลี่ยนเป็นคลิก () ทุกอย่างไปถูกต้อง จริงๆแล้วฉันไม่เคยเจอกับปัญหานี้มาก่อน


0

องค์ประกอบใหม่

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

  1. องค์ประกอบที่เลือกโดยตัวเลือกแรกเช่น $ ("body") จะต้องมีอยู่ในเวลาที่มีการประกาศเป็นอย่างอื่นไม่มีสิ่งใดแนบมาด้วย
  2. คุณต้องใช้อาร์กิวเมนต์สามตัวในฟังก์ชัน. on () รวมถึงตัวเลือกที่ถูกต้องสำหรับองค์ประกอบเป้าหมายของคุณเป็นอาร์กิวเมนต์ที่สอง

-1
$('.UPDATE').click(function(){ }); **V/S**    
$(document).on('click','.UPDATE',function(){ });

$(document).on('click','.UPDATE',function(){ });
  1. มันจะมีประสิทธิภาพมากกว่า $ ('. UPDATE'). คลิก (ฟังก์ชั่น () {});
  2. มันสามารถใช้หน่วยความจำน้อยลงและทำงานสำหรับองค์ประกอบที่เพิ่มแบบไดนามิก
  3. บางครั้งข้อมูลที่ดึงข้อมูลแบบไดนามิกพร้อมปุ่มแก้ไขและลบไม่ได้สร้างเหตุการณ์ JQuery ในเวลาที่แก้ไขหรือลบข้อมูลของข้อมูลแถวในรูปแบบเวลานั้น$(document).on('click','.UPDATE',function(){ });จะทำงานได้อย่างมีประสิทธิภาพเหมือนกับข้อมูลที่ดึงข้อมูลเดียวกันโดยใช้ jquery ปุ่มไม่ทำงานเมื่อมีการอัปเดตหรือลบ:

ป้อนคำอธิบายรูปภาพที่นี่


$ (เอกสาร) .on ('คลิก', '. UPDATE', ฟังก์ชัน () {}); 1) มีประสิทธิภาพมากกว่า $ ('. UPDATE'). คลิก (function () {}); 2) สามารถใช้หน่วยความจำน้อยลงและทำงานกับองค์ประกอบที่เพิ่มเข้ามาแบบไดนามิก 3) บางครั้งข้อมูลที่ดึงข้อมูลแบบไดนามิกพร้อมปุ่มแก้ไขและลบไม่ได้สร้างเหตุการณ์ JQuery ณ เวลาที่แก้ไขหรือลบข้อมูลของข้อมูลแถวในรูปแบบเวลานั้น $ (เอกสาร) .on ('คลิก', '. UPDATE', function () {}); ทำงานได้อย่างมีประสิทธิภาพ [เช่นข้อมูลที่ดึงมาเดียวกันโดยใช้ jquery ปุ่มไม่ทำงานในเวลาที่อัปเดตหรือลบ
จ้าง Devang
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.