latar belakang
Ada beberapa masalah kecil saat mengikat peristiwa menggunakan AddEventListener () atau attachEvent () di JavaScript:
1. Fungsi anonim yang ditambahkan menggunakan AddEventListener () atau attachEvent () tidak dapat dihapus.
Salinan kode adalah sebagai berikut: var obtn = document.geteLementById ('btn');
OBTN.AdDeventListener ('klik', fungsi () {
alert ('tombol diklik')
},PALSU)
Obtn.reomveeventListener ('klik', function () {
alert ('tombol diklik')
},PALSU)
// Peristiwa di OBTN tidak dapat dihapus karena fungsi anonim disahkan
2. Di IE6-IE8, masalah eksekusi pesanan terbalik dari beberapa peristiwa dibatasi menggunakan attachEvent ().
Salinan kode adalah sebagai berikut:
var obtn = document.geteLementById ('btn');
obl.attachevent ('onClick', function () {
waspada (1)
})
obl.attachevent ('onClick', function () {
waspada (2)
})
obl.attachevent ('onClick', function () {
waspada (3)
})
// EIE9+ Pesanan Eksekusi 1, 2, 3
// Perintah eksekusi di bawah IE6-IE8 3, 2, 1
Menyelesaikan masalahnya
Saya ingin menulis modul pengikat acara lintas-browser sehingga dapat digunakan kembali nanti, dan pada saat yang sama saya ingin menyelesaikan masalah banding. JQuery menggunakan antrian acara dan mekanisme caching data untuk menyelesaikan masalah ini. Saya melihat kode sumber yang relevan. Itu sangat rumit. Saya mencoba beberapa metode sendiri dan nyaris tidak menerapkannya. Kode ini diposting di objek yang berorientasi pada objek, dan saya tidak ingin orang melihatnya rumit, jadi saya mengubahnya menjadi fungsi untuk mengaturnya.
Salinan kode adalah sebagai berikut:
/*Mengikat antarmuka acara
*
*@param {dom-dom} dan {type-string} dan {fn-function} parameter opsional {fnname-string}
*@Execute Buat antrian acara dan tambahkan ke properti objek DOM.
Tambahkan event handler (fungsi) ke antrian acara
Pengidentifikasi dapat ditambahkan ke penangan acara untuk menghapus event handler yang ditentukan
*/
Function Bind (dom, type, fn, fnname) {
dom.eventqueue = dom.eventqueue || {};
dom.eventqueue [type] = dom.eventqueue [type] || {};
dom.handler = dom.handler || {};
if (! fnname) {
indeks var = panjang queuel (dom, type);
dom.eventqueue [type] ['fnqueue'+index] = fn;
}
kalau tidak {
dom.eventqueue [type] [fnname] = fn;
};
if (! dom.handler [type]) bindevent (dom, type);
};
/*Acara yang mengikat
*
*@param {dom-dom} dan {type-string}
*@Execute Expect hanya terikat sekali, penangan digunakan untuk melintasi penangan (fungsi) kejadian dalam antrian acara eksekusi
*@caller bind ()
*/
fungsi bindevent (dom, type) {
dom.handler [type] = function () {
untuk (var guid di dom.eventqueue [type]) {
dom.eventqueue [type] [Guid] .call (DOM);
}
};
if (window.addeventListener) {
dom.addeventListener (type, dom.handler [type], false);
}
kalau tidak {
dom.attachevent ('on'+type, dom.handler [type]);
};
};
/*Hapus antarmuka untuk acara
*
*@param {dom-dom} dan {type-string} parameter opsional {fnname-function}
*@Execute Jika tidak ada pengidentifikasi, jalankan unbindevent ()
Jika ada pengidentifikasi, event handler yang ditentukan dihapus. Jika panjang antrian acara adalah 0, unbindevent () dieksekusi.
*/
fungsi unbind (dom, type, fnname) {
var hasqueue = dom.eventqueue && dom.eventqueue [type];
if (! hasqueue) kembali;
if (! fnname) {
Unbindevent (dom, ketik)
}
kalau tidak {
hapus dom.eventqueue [type] [fnname];
if (queuelength (dom, type) == 0) unbindevent (dom, type);
};
};
/*Hapus acara
*
*@param {dom-dom} dan {type-string}
*@Execute menghapus event handler yang terikat dan menghapus antrian acara
*@caller unbind ()
*/
fungsi unbindevent (dom, type) {
if (window.removeeventListener) {
dom.removeeventlistener (type, dom.handler [type])
}
kalau tidak {
dom.detachevent (type, dom.handler [type])
}
hapus dom.eventqueue [tipe];
};
/*Hakim Panjang Antrian Acara
*
*@param {dom-dom} dan {type-string}
*@caller bind () unbind ()
*/
fungsi queuelength (dom, type) {
indeks var = 0;
untuk (panjang var di dom.eventqueue [type]) {
indeks ++;
}
indeks pengembalian;
};
Cara menggunakan
Salinan kode adalah sebagai berikut:
var obtn = document.geteLementById ('btn');
// acara yang mengikat
// Bind Three Click Event Functions secara bersamaan untuk tombol
// Perintah eksekusi di bawah IE6-IE8 tetap tidak berubah
bind (obtn, 'click', function () {
waspada (1);
})
bind (obtn, 'click', function () {
waspada (2);
}, 'myfn')
bind (obtn, 'click', function () {
waspada (3);
})
// Hapus acara
// Hapus semua fungsi Acara Klik Bound, Dukungan Penghapusan Fungsi Anonim
unbind (obtn, 'click')
// Hapus hanya fungsi acara dengan pengidentifikasi myfn
unbind (obtn, 'klik', 'myfn')
Ide Program
Gagasan utama dari program ini adalah menambahkan antrian acara sebagai atribut objek elemen DOM ke elemen DOM tanpa mencemari lingkungan global. Ini dapat memecahkan masalah penyimpanan data dari beberapa fungsi acara dari berbagai elemen DOM yang mengikat dengan berbagai jenis acara.
Salinan kode adalah sebagai berikut:
// antrian acara di elemen DOM
dom {
EventQueue: {
'Klik': {
fnqueue1: fungsi,
MyFN: Fungsi,
fnqueue3: fungsi
}
'Mouseover': {
fnqueue1: fungsi,
fnqueue2: fungsi
}
}
}
Setiap kali, fungsi acara pertama kali ditambahkan ke antrian acara dari jenis acara yang sesuai, dan acara hanya terikat sekali. Ketika suatu peristiwa dipicu, fungsi acara pawang dieksekusi, dan pawang melintasi fungsi acara dalam antrian acara eksekusi.
unbind () menghapus semua fungsi acara terikat jika tidak ada pengidentifikasi yang masuk, mendukung menghapus fungsi anonim, dan menghapus fungsi acara yang ditentukan jika ada pengidentifikasi.
Logika program tidak rumit, dan mungkin ada bug dan masalah kinerja. Jika Anda tertarik, Anda dapat membimbing dan berkomunikasi.