Perbedaan antara fungsi jQuery `click`,` bind`, `live`,` delegate`, `trigger` dan` on` (dengan contoh)?

139

Saya telah membaca dokumentasi masing-masing fungsi jQuery official website, tetapi tidak ada daftar perbandingan antara fungsi-fungsi di bawah ini:

$().click(fn)
$().bind('click',fn)
$().live('click',fn)
$().delegate(selector, 'click', fn)
$().trigger('click') // UPDATED
$().on('click', selector ,fn); // more UPDATED

Harap hindari tautan referensi apa pun.

Bagaimana semua fungsi di atas berfungsi dengan baik dan mana yang lebih disukai dalam situasi apa?

Catatan: Jika ada fungsi lain yang memiliki fungsionalitas atau mekanisme yang sama, Maka jelaskan.

Memperbarui

Saya juga melihat $.triggerfungsi. Apakah fungsinya mirip dengan fungsi di atas?

Lebih Banyak Pembaruan

Sekarang .onditambahkan dalam v1.7 dan saya pikir ini entah bagaimana mencakup semua persyaratan fungsi di atas bersama-sama.

diEcho
sumber
3
@Saya Suka PHP, kadang-kadang orang memilih sesuatu jika mereka tidak merasa itu adalah pertanyaan yang tidak bisa dijawab dengan manual atau tampaknya menjadi pertanyaan pekerjaan rumah. jangan khawatir, orang lain akan memilihnya jika mereka merasa itu berguna.
typeoneerror
@ Typeoneerror - Terima kasih atas dukungannya, saya sudah membaca manual dan ketika saya tidak mengerti perbedaan yang jelas maka saya posting di sini.
diEcho
3
@I Like PHP - Diedit pertanyaan untuk sedikit pembersihan ... ini sering ditanyakan tetapi jarang dengan cara ini, ini bisa dengan mudah menjadi sumber daya yang dapat digunakan oleh google. Saya setuju entri wiki-ish dari sesuatu seperti ini akan sangat membantu, saya melihat kebingungan di sekitar ini, terutama dengan .live()dan .delegate()hampir setiap hari, +1 untuk pertanyaan yang benar-benar valid.
Nick Craver
@Nick Craver Terima kasih telah mengedit, sebenarnya saya buruk dalam bahasa Inggris (lol). apakah ada maunal / referensi yang bagaimana kita memposting pertanyaan SO. atau itu baru saja datang dari pengalaman
diEcho
@Saya Suka PHP - Ini sedikit dari keduanya, ada banyak sekali FAQ untuk SO di sini: meta.stackexchange.com/questions/7931 Untuk ungkapan / komentar, Anda baru mulai mempelajari apa yang cocok dan merupakan cara terbaik untuk sampaikan pemikiran Anda, kode> deskripsi apa pun kadang-kadang, menggunakan kata kunci yang tepat, penandaan yang tepat, semakin lama Anda di sini, saya kira, saya melihat banyak poster yang membaik seiring waktu. Mengenai hasil edit Anda, .trigger()aktifkan event handler ... Saya akan menambahkan deskripsi ke jawaban saya di bawah ini.
Nick Craver

Jawaban:

162

Sebelum Anda membaca ini, tarik daftar acara ini di halaman lain, API itu sendiri sangat membantu, dan semua yang saya diskusikan di bawah ini terhubung langsung dari halaman ini .

Pertama, .click(function)secara harfiah merupakan jalan pintas untuk .bind('click', function), mereka setara. Gunakan mereka ketika mengikat pawang langsung ke suatu elemen , seperti ini:

$(document).click(function() {
  alert("You clicked somewhere in the page, it bubbled to document");
});

Jika elemen ini diganti atau dibuang, pawang ini tidak akan ada lagi. Juga elemen-elemen yang tidak ada ketika kode ini dijalankan untuk melampirkan handler (mis. Pemilih menemukannya kemudian) tidak akan mendapatkan handler.

.live()dan .delegate()sama-sama terkait, .delegate()benar-benar menggunakan .live()internal, mereka berdua mendengarkan acara menggelembung. Ini berfungsi untuk elemen baru dan lama , mereka menggelembungkan acara dengan cara yang sama. Anda menggunakan ini ketika elemen Anda dapat berubah, misalnya menambahkan baris baru, daftar item, dll. Jika Anda tidak memiliki orang tua / leluhur umum yang akan tetap berada di halaman dan tidak diganti pada titik mana pun, gunakan .live(), seperti ini:

$(".clickAlert").live('click', function() {
  alert("A click happened");
});

Namun jika Anda memiliki elemen induk di suatu tempat yang tidak diganti (jadi penangan eventnya tidak akan selamat tinggal) Anda harus menanganinya .delegate(), seperti ini:

$("#commonParent").delegate('.clickAlert', 'click', function() {
  alert("A click happened, it was captured at #commonParent and this alert ran");
});

Ini berfungsi hampir sama dengan .live(), tetapi peristiwa itu lebih sedikit meluap sebelum ditangkap dan penangan dieksekusi. Penggunaan umum kedua dari ini adalah mengatakan perubahan kelas Anda pada suatu elemen, tidak lagi cocok dengan pemilih yang Anda gunakan ... dengan metode ini pemilih dievaluasi pada saat acara , jika cocok, pawang berjalan .. . jadi elemen tidak lagi cocok dengan masalah pemilih, itu tidak akan dijalankan lagi. Dengan .click()Namun, event handler adalah terikat tepat pada elemen DOM, fakta bahwa itu tidak cocok pemilih apa pun yang digunakan untuk menemukan itu tidak relevan ... acara terikat dan itu tinggal sampai elemen yang hilang, atau pawang dihapus melalui .unbind().

Namun yang umum digunakan untuk .live()dan .delegate()adalah kinerja . Jika Anda berurusan dengan banyak elemen, melampirkan handler klik langsung ke setiap elemen itu mahal dan memakan waktu. Dalam kasus ini, lebih ekonomis untuk mengatur handler tunggal dan membiarkannya bekerja, lihat pertanyaan ini di mana ia membuat perbedaan besar , itu adalah contoh aplikasi yang bagus.


Memicu - untuk pertanyaan yang diperbarui

Ada 2 fungsi pemicu event-handler utama yang tersedia, mereka termasuk dalam kategori "Event Handler Attachment" yang sama di API , ini adalah .trigger()dan .triggerHandler(). .trigger('eventName')memiliki beberapa pintasan bawaan untuk acara umum, misalnya:

$().click(fn); //binds an event handler to the click event
$().click();   //fires all click event handlers for this element, in order bound

Anda dapat melihat daftar termasuk pintasan ini di sini .

Adapun perbedaannya, .trigger()memicu event handler (tetapi bukan tindakan default sebagian besar waktu, misalnya menempatkan kursor di tempat yang tepat di klik <textarea>). Hal ini menyebabkan event handler terjadi sesuai dengan urutan mereka terikat (seperti acara asli), menembakkan aksi event asli, dan menggembungkan DOM.

.triggerHandler()biasanya untuk tujuan yang berbeda, di sini Anda hanya mencoba memecat pawang yang terikat, itu tidak menyebabkan acara asli menyala, misalnya mengirimkan formulir. Itu tidak menggembungkan DOM, dan itu tidak dapat dilepas (mengembalikan apa pun yang ditangani pengendali acara terakhir untuk acara itu kembali). Misalnya jika Anda ingin memicu suatu focusperistiwa tetapi tidak benar-benar fokus objek, Anda hanya ingin kode Anda terikat .focus(fn)untuk menjalankan, ini akan melakukan itu, sedangkan .trigger()akan melakukannya serta benar-benar fokus elemen dan menggelembung ke atas.

Ini adalah contoh dunia nyata:

$("form").submit(); //actually calling `.trigger('submit');`

Ini akan menjalankan penangan kirim apa pun, misalnya plugin validasi jQuery , lalu coba kirim <form>. Namun jika Anda hanya ingin memvalidasi, karena terhubung melalui submitevent handler, tetapi tidak mengirimkan <form>setelahnya, Anda dapat menggunakan .triggerHandler('submit'), seperti ini:

$("form").triggerHandler('submit');

Plugin mencegah pawang mengirimkan formulir dengan membom keluar jika pemeriksaan validasi tidak lulus, tetapi dengan metode ini kami tidak peduli apa fungsinya. Apakah itu dibatalkan atau tidak, kami tidak mencoba mengirimkan formulir, kami hanya ingin memicunya untuk memvalidasi ulang dan tidak melakukan hal lain. ( Penafian: Ini adalah contoh berlebihan karena ada .validate()metode di plugin, tapi ini ilustrasi maksud yang baik)

Nick Craver
sumber
Sangat teliti. Satu koreksi kecil: triggertidak memecat acara asli. Maksud saya maksud suatu peristiwa disimulasikan dengan fireEvent(IE) atau dispatchEvent(w3c).
Crescent Fresh
@Crescent - Diperbarui agar tidak terlalu mendua, maksud saya bahwa itu akan memunculkan aksi peristiwa asli , seperti pengiriman formulir, tautan berikut dll ... semoga pembaruannya lebih jelas :)
Nick Craver
@Sekarang dari apa yang saya baca, sepertinya pendapat Anda live()berbeda dari yang Anda berikan di sini: stackoverflow.com/questions/3981762/... Apakah 'berat' masih menjadi perhatian saat digunakan live()?
Yahel
@yahelc - Ya, tentu saja ... jawaban ini benar-benar membandingkan opsi penangan acara dan tujuan spesifik mereka. Biaya berat vs jumlah binding awal vs jika Anda menambahkan sesuatu secara dinamis vs pemilih awal semua masih merupakan kekhawatiran yang valid. Jika Anda struktur halaman sedang tidak bahwa besar Anda Anda tidak memiliki bahwa banyak peristiwa maka Anda baik-baik saja sedang ... keprihatinan atas berat berbanding lurus dengan ukuran / kedalaman struktur dan jumlah peristiwa (dari jenis .live()panggilan Anda mendengarkan, misalnya click) yang sedang dihasilkan, karena itu menjalankan penyeleksi untuk masing-masing.
Nick Craver
1
di jQuery 1.7, live () tidak digunakan lagi karena $ (dokumen) .on ().
Sinkronisasi
28

Dua yang pertama adalah setara.

// The following two statements do the same thing:
$("blah").click( function() { alert( "Click!" ); } );
$("blah").bind( "click", function() { alert( "Click!" ); } ); 

Namun, yang kedua dapat digunakan untuk mengikat lebih dari satu peristiwa pada saat yang sama, dengan menetapkan beberapa nama peristiwa yang dipisahkan oleh ruang:

$("blah").bind( "click mouseover mouseout", function() { alert( "Click! Or maybe mouse moved." ); } ); 

The .liveMetode ini lebih menarik. Perhatikan contoh berikut:

<a class="myLink">A link!</a>
<a id="another">Another link!</a>

<script>
    $("a.myLink").click( function() { alert( 'Click!' ); } );

    $("a#another").addClass( "myLink" );
</script>

Setelah baris kedua skrip dijalankan, tautan kedua juga akan memiliki kelas CSS "myLink". Tapi itu tidak akan memiliki pengendali acara, karena tidak memiliki kelas ketika acara itu dilampirkan.

Sekarang anggap Anda ingin sebaliknya: setiap kali tautan dengan kelas "myLink" muncul di suatu tempat di halaman, Anda ingin memiliki pengendali acara yang sama secara otomatis. Ini sangat umum ketika Anda memiliki beberapa jenis daftar atau tabel, di mana Anda menambahkan baris atau sel secara dinamis, tetapi ingin semuanya berperilaku dengan cara yang sama. Alih-alih pergi kesusahan menetapkan penangan acara yang baru setiap kali, Anda dapat menggunakan .livemetode ini:

<a class="myLink">A link!</a>
<a id="another">Another link!</a>

<script>
    $("a.myLink").live( "click", function() { alert( 'Click!' ); } );

    $("a#another").addClass( "myLink" );
</script>

Dalam contoh ini, tautan kedua juga akan mendapatkan pengendali acara segera setelah mendapat kelas "myLink". Sihir! :-)

Tentu saja, itu tidak literal. Apa yang .livesebenarnya dilakukan adalah melampirkan handler bukan ke elemen yang ditentukan itu sendiri, tetapi ke akar dari pohon HTML (elemen "body"). Acara di DHTML memiliki fitur lucu "menggelegak". Pertimbangkan ini:

<div> <a> <b>text</b> </a> </div>

Jika Anda mengklik "teks", maka pertama elemen <b> akan mendapatkan acara "klik". Setelah itu, elemen <a> akan mendapatkan acara "klik". Dan setelah itu elemen <div> akan mendapatkan acara "klik". Dan seterusnya - sampai ke elemen <body>. Dan di situlah jQuery akan menangkap acara dan melihat apakah ada penangan "langsung" yang berlaku untuk elemen yang menyebabkan acara di tempat pertama. Rapi!

Dan akhirnya, .delegatemetodenya. Ini hanya membawa semua anak-anak elemen Anda yang sesuai dengan pemilih yang diberikan dan melampirkan pawang "hidup" kepada mereka. Lihatlah:

$("table").delegate( "td", "click", function() { alert( "Click!" ); } );

// Is equivalent to:
$("table").each( function() {
    $(this).find( "td" ).live( "click", function() { alert( "Click!" ); } );
} );

Pertanyaan?

Fyodor Soikin
sumber
Agar akurat, .live()mengikat ke documenttidak <body>:) Anda dapat melihat demo di sini, cukup tarik konsol untuk memeriksa: jsfiddle.net/aJy2B
Nick Craver
3
Lebih mudah untuk menjelaskannya dengan cara ini. :-)
Fyodor Soikin
4
Cukup adil pada bagian "tubuh", tetapi "semua jalan ke elemen <body>" salah, peristiwa terus meluap melewati sana, dan itu bukan tempat .live()tinggal penangan, itu di atas itu, pada document:) Anda dapat melihat demo dari ini di sini: jsfiddle.net/S2VBX
Nick Craver
8

Pada jQuery 1.7, metode .live () sudah tidak digunakan lagi. Jika Anda menggunakan versi jQuery <1.7 daripada yang disarankan untuk menggunakan .delegate () di atas .live ().

.live () sekarang telah diganti dengan .on ().

Cara terbaik untuk langsung menuju ke situs jQuery untuk informasi lebih lanjut, tetapi berikut adalah versi terbaru dari metode .on ():

.on( events [, selector] [, data], handler(eventObject) )
.on( events-map [, selector] [, data] )

http://api.jquery.com/on/

Jonathan Tonge
sumber
2

$().click(fn)dan $().bind('click', fn)identik pada pandangan pertama, tetapi $.bindversi ini lebih kuat karena dua alasan:

  1. $().bind() memungkinkan Anda untuk menetapkan satu penangan ke beberapa acara, misalnya, $().bind('click keyup', fn) ,.
  2. $().bind()mendukung acara dengan spasi nama - fitur hebat jika Anda ingin menghapus (melepaskan ikatan) hanya event handler tertentu yang terikat dengan elemen - baca lebih lanjut di Acara dengan Nama .

Live vs delegate: ini sudah dijawab di balasan yang lain.

fbuchinger
sumber
1

Di sinilah membaca API dapat membantu. Namun, saya tahu dari atas kepala saya, sehingga Anda dapat terus menjadi malas (yay!).

$('#something').click(fn);
$('#something').bind('click',fn);

Tidak ada perbedaan di sini (yang saya tahu). .clickhanyalah metode kenyamanan / penolong bagi.bind('click'

// even after this is called, all <a>s in
// <div class="dynamic_els"> will continue
// to be assigned these event handlers

$('div.dynamic_els a').live(‘click’,fn);

Ini sangat berbeda, karena .livemenambahkan acara ke pemilih yang Anda lewati (yang belum Anda datangi) dan terus melihat DOM saat simpul dimasukkan / dihapus

$('#some_element').delegate('td','click',fn);

Ini hanya berbeda karena cara Anda menugaskan penangan acara. .delegatedipusatkan pada acara DOM yang menggelegak. Prinsip dasarnya adalah bahwa setiap peristiwa meluap ke atas melalui pohon DOM hingga mencapai elemen root ( documentatau windowatau <html>atau<body> , saya tidak ingat persis).

Either way, Anda mengikat onclickpawang ke semua yang ada <td>di dalam $('#some_element')(Anda harus menentukan pemilih, meskipun Anda bisa mengatakan $(document)). Ketika salah satu anaknya diklik, acara akan muncul hingga<td> . Anda kemudian dapat mengekstrak elemen sumber acara (yang jQuery lakukan untuk Anda secara otomatis).

Ini berguna ketika ada banyak elemen dan Anda hanya memiliki hanya beberapa (atau satu titik pusat) yang akan dilalui oleh peristiwa ini. Ini menghemat upaya browser dan memori untuk mengkonsolidasikan penangan acara ini menjadi lebih sedikit objek.

Dan Beam
sumber
1
.live() juga bekerja dari acara menggelegak, sebenarnya .delegate()adalah pembungkus untuk .live(), itu hanya menambahkan konteks dan mengikat unsur lain selain documentuntuk menangkap gelembung. Saya pikir pemahaman Anda tentang bagaimana cara kerja penangan yang menggelegak sedikit (ini adalah aspek yang paling sering disalahpahami dari jQuery 1.4 saya pikir). Pawang hanya pada elemen tempat Anda mengikatnya, jadi elemen apa pun yang Anda panggil .delegate(), atau documentdalam hal .live(), ketika suatu peristiwa meletus ke sana, ia memeriksa target untuk melihat apakah itu cocok dengan pemilih, dan jika demikian dijalankan.
Nick Craver