mirror of
https://github.com/twbs/bootstrap.git
synced 2025-08-08 06:36:33 +02:00
fix: make EventHandler better handle mouseenter/mouseleave events (#33310)
* fix: make EventHandler better handle mouseenter/mouseleave events * refactor: simplify custom events regex and move it to a variable
This commit is contained in:
@@ -22,6 +22,7 @@ const customEvents = {
|
||||
mouseenter: 'mouseover',
|
||||
mouseleave: 'mouseout'
|
||||
}
|
||||
const customEventsRegex = /^(mouseenter|mouseleave)/i
|
||||
const nativeEvents = new Set([
|
||||
'click',
|
||||
'dblclick',
|
||||
@@ -113,7 +114,7 @@ function bootstrapDelegationHandler(element, selector, fn) {
|
||||
|
||||
if (handler.oneOff) {
|
||||
// eslint-disable-next-line unicorn/consistent-destructuring
|
||||
EventHandler.off(element, event.type, fn)
|
||||
EventHandler.off(element, event.type, selector, fn)
|
||||
}
|
||||
|
||||
return fn.apply(target, [event])
|
||||
@@ -144,14 +145,7 @@ function normalizeParams(originalTypeEvent, handler, delegationFn) {
|
||||
const delegation = typeof handler === 'string'
|
||||
const originalHandler = delegation ? delegationFn : handler
|
||||
|
||||
// allow to get the native events from namespaced events ('click.bs.button' --> 'click')
|
||||
let typeEvent = originalTypeEvent.replace(stripNameRegex, '')
|
||||
const custom = customEvents[typeEvent]
|
||||
|
||||
if (custom) {
|
||||
typeEvent = custom
|
||||
}
|
||||
|
||||
let typeEvent = getTypeEvent(originalTypeEvent)
|
||||
const isNative = nativeEvents.has(typeEvent)
|
||||
|
||||
if (!isNative) {
|
||||
@@ -171,6 +165,24 @@ function addHandler(element, originalTypeEvent, handler, delegationFn, oneOff) {
|
||||
delegationFn = null
|
||||
}
|
||||
|
||||
// in case of mouseenter or mouseleave wrap the handler within a function that checks for its DOM position
|
||||
// this prevents the handler from being dispatched the same way as mouseover or mouseout does
|
||||
if (customEventsRegex.test(originalTypeEvent)) {
|
||||
const wrapFn = fn => {
|
||||
return function (event) {
|
||||
if (!event.relatedTarget || (event.relatedTarget !== event.delegateTarget && event.relatedTarget.contains(event.delegateTarget))) {
|
||||
return fn.call(this, event)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (delegationFn) {
|
||||
delegationFn = wrapFn(delegationFn)
|
||||
} else {
|
||||
handler = wrapFn(handler)
|
||||
}
|
||||
}
|
||||
|
||||
const [delegation, originalHandler, typeEvent] = normalizeParams(originalTypeEvent, handler, delegationFn)
|
||||
const events = getEvent(element)
|
||||
const handlers = events[typeEvent] || (events[typeEvent] = {})
|
||||
@@ -219,6 +231,12 @@ function removeNamespacedHandlers(element, events, typeEvent, namespace) {
|
||||
})
|
||||
}
|
||||
|
||||
function getTypeEvent(event) {
|
||||
// allow to get the native events from namespaced events ('click.bs.button' --> 'click')
|
||||
event = event.replace(stripNameRegex, '')
|
||||
return customEvents[event] || event
|
||||
}
|
||||
|
||||
const EventHandler = {
|
||||
on(element, event, handler, delegationFn) {
|
||||
addHandler(element, event, handler, delegationFn, false)
|
||||
@@ -272,7 +290,7 @@ const EventHandler = {
|
||||
}
|
||||
|
||||
const $ = getjQuery()
|
||||
const typeEvent = event.replace(stripNameRegex, '')
|
||||
const typeEvent = getTypeEvent(event)
|
||||
const inNamespace = event !== typeEvent
|
||||
const isNative = nativeEvents.has(typeEvent)
|
||||
|
||||
|
Reference in New Issue
Block a user