Pertanyaan lama, tetapi masih belum ada jawaban terbaru yang bagus dengan wawasan imo.
Saat ini, semua browser mendukung mouseover/mouseout
dan mouseenter/mouseleave
. Meskipun demikian, jQuery tidak mendaftarkan handler Anda mouseenter/mouseleave
, tetapi diam-diam menempatkannya pada pembungkus mouseover/mouseout
seperti yang ditunjukkan kode berikut dan membuat interpretasinya sendiri yang sedikit berbeda mouseenter/mouseleave
.
Perilaku persis peristiwa sangat relevan pada "penangan delegasi". Sayangnya, jQuery juga memiliki interpretasi yang berbeda tentang apa yang menjadi penangan delegasi dan apa yang harus mereka terima untuk acara. Fakta itu ditunjukkan dalam jawaban lain untuk acara klik yang lebih sederhana.
Jadi bagaimana cara menjawab pertanyaan tentang jQuery dengan benar, yang menggunakan kata-kata Javascript untuk acara dan penangan, tetapi membuat keduanya berbeda dan bahkan tidak menyebutkannya dalam dokumentasinya?
Pertama perbedaan dalam Javascript "asli":
- kedua
- mouse dapat "melompat" dari elemen luar / luar ke elemen dalam / terdalam ketika bergerak lebih cepat daripada browser mengambil sampel posisinya
- ada
enter/over
yang sesuai leave/out
(mungkin terlambat / gelisah)
- acara pergi ke elemen yang terlihat di bawah pointer (tidak terlihat → tidak dapat menjadi target)
mouseenter/mouseleave
- dikirimkan ke elemen tempat terdaftar (target)
- kapan saja elemen atau keturunan apa pun (misalnya dengan melompat) dimasukkan / kiri
- itu tidak bisa menggelembung, karena secara konseptual keturunan dianggap sebagai bagian dari unsur yang dimaksud, yaitu tidak ada anak dari mana peristiwa lain dapat berasal (dengan arti "masuk / pergi" orang tua ?!)
- anak-anak juga mungkin memiliki penangan yang sama yang terdaftar, yang masuk / pergi dengan benar, tetapi tidak terkait dengan siklus masuk / keluar orang tua
mouseover/mouseout
- target adalah elemen aktual di bawah pointer
- target tidak boleh dua hal: yaitu bukan orang tua dan anak pada saat yang sama
- acara tidak bisa "bersarang"
- sebelum seorang anak bisa "overed", orang tua perlu "keluar"
- dapat menggelembung, karena target / relatedTarget menunjukkan di mana peristiwa itu terjadi
Setelah beberapa pengujian, ini menunjukkan bahwa selama Anda tidak menggunakan jQuery "delegate handler with pendaftaran pemilih", emulasi tidak perlu tetapi masuk akal: Ini menyaring mouseover/mouseout
peristiwa yang mouseenter/mouseleave
tidak akan didapat. Targetnya berantakan. Real mouseenter/mouseleave
akan memberikan elemen pawang sebagai target, emulasi mungkin mengindikasikan anak-anak dari elemen itu, yaitu apa pun yang mouseover/mouseout
dibawa.
const list = document.getElementById('log');
const outer = document.getElementById('outer');
const $outer = $(outer);
function log(tag, event) {
const li = list.insertBefore(document.createElement('li'), list.firstChild);
// only jQuery handlers have originalEvent
const e = event.originalEvent || event;
li.append(`${tag} got ${e.type} on ${e.target.id}`);
}
outer.addEventListener('mouseenter', log.bind(null, 'JSmouseenter'));
$outer.on('mouseenter', log.bind(null, '$mouseenter'));
div {
margin: 20px;
border: solid black 2px;
}
#inner {
min-height: 80px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body>
<div id=outer>
<ul id=log>
</ul>
</div>
</body>