Created
January 16, 2015 04:20
-
-
Save jarek-foksa/831284c74d64e1b6be69 to your computer and use it in GitHub Desktop.
Workaround for Chrome bug #333868
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/********************************************************************************************** | |
Workaround for Chrome bug #333868 which breaks "mouseenter" and "mouseleave" events. | |
*********************************************************************************************/ | |
(function() { | |
var $addEventListener = EventTarget.prototype.addEventListener; | |
var $removeEventListener = EventTarget.prototype.removeEventListener; | |
const MOUSEENTER_TO_MOUSEOVER_SYM = Symbol(); | |
const MOUSELEAVE_TO_MOUSEOUT_SYM = Symbol(); | |
var isDetached = function(element) { | |
while (element.parentNode || element.host) { | |
element = element.parentNode || element.host; | |
} | |
if (element === document) { | |
return false; | |
} | |
else { | |
return true; | |
} | |
}; | |
EventTarget.prototype.addEventListener = function(eventName, listener) { | |
var that = this; | |
if (eventName === "mouseenter") { | |
var mouseEnterListener = listener; | |
var mouseOverListener = function(event) { | |
var eventIsRepeated; | |
if (event.relatedTarget === null) { | |
eventIsRepeated = false; | |
} | |
else if (event.relatedTarget === that) { | |
eventIsRepeated = true; | |
} | |
else { | |
eventIsRepeated = that.contains(event.relatedTarget) || isDetached(event.relatedTarget); | |
} | |
if (eventIsRepeated === false) { | |
mouseEnterListener(event); | |
} | |
}; | |
if (!this[MOUSEENTER_TO_MOUSEOVER_SYM]) { | |
this[MOUSEENTER_TO_MOUSEOVER_SYM] = new Map(); | |
} | |
this[MOUSEENTER_TO_MOUSEOVER_SYM].set(mouseEnterListener, mouseOverListener); | |
this.addEventListener("mouseover", mouseOverListener); | |
} | |
else if (eventName === "mouseleave") { | |
var mouseLeaveListener = listener; | |
var mouseOutListener = function(event) { | |
var eventIsRepeated; | |
if (event.relatedTarget === null) { | |
eventIsRepeated = false; | |
} | |
else if (event.relatedTarget === that) { | |
eventIsRepeated = true; | |
} | |
else { | |
eventIsRepeated = that.contains(event.relatedTarget) || isDetached(event.relatedTarget); | |
} | |
if (eventIsRepeated === false) { | |
mouseLeaveListener(event); | |
} | |
}; | |
if (!this[MOUSELEAVE_TO_MOUSEOUT_SYM]) { | |
this[MOUSELEAVE_TO_MOUSEOUT_SYM] = new Map(); | |
} | |
this[MOUSELEAVE_TO_MOUSEOUT_SYM].set(mouseLeaveListener, mouseOutListener); | |
this.addEventListener("mouseout", mouseOutListener); | |
} | |
else { | |
$addEventListener.call(this, eventName, listener); | |
} | |
}; | |
EventTarget.prototype.removeEventListener = function(eventName, listener) { | |
var that = this; | |
if (eventName === "mouseenter") { | |
if (!this[MOUSEENTER_TO_MOUSEOVER_SYM]) { | |
return; | |
} | |
var mouseEnterListener = listener; | |
var mouseOverListener = this[MOUSEENTER_TO_MOUSEOVER_SYM].get(mouseEnterListener); | |
if (mouseOverListener) { | |
that.removeEventListener("mouseover", mouseOverListener); | |
that[MOUSEENTER_TO_MOUSEOVER_SYM].delete(mouseEnterListener); | |
} | |
} | |
else if (eventName === "mouseleave") { | |
if (!this[MOUSELEAVE_TO_MOUSEOUT_SYM]) { | |
return; | |
} | |
var mouseLeaveListener = listener; | |
var mouseOutListener = this[MOUSELEAVE_TO_MOUSEOUT_SYM].get(mouseLeaveListener); | |
if (mouseOutListener) { | |
that.removeEventListener("mouseout", mouseOutListener); | |
that[MOUSELEAVE_TO_MOUSEOUT_SYM].delete(mouseLeaveListener); | |
} | |
} | |
else { | |
$removeEventListener.call(this, eventName, listener); | |
} | |
}; | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment