Skip to content

Instantly share code, notes, and snippets.

@jarek-foksa
Created January 16, 2015 04:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jarek-foksa/831284c74d64e1b6be69 to your computer and use it in GitHub Desktop.
Save jarek-foksa/831284c74d64e1b6be69 to your computer and use it in GitHub Desktop.
Workaround for Chrome bug #333868
/**********************************************************************************************
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