Skip to content

Instantly share code, notes, and snippets.

@edom18
Created September 14, 2012 02:05
Show Gist options
  • Save edom18/3719372 to your computer and use it in GitHub Desktop.
Save edom18/3719372 to your computer and use it in GitHub Desktop.
forked: mouseout / mouseoverのrelatedTargetの意味
/* #! scss */
#status {
width: 10px;
height: 10px;
margin-top: 10px;
background: green;
&.error {
background: red;
}
}
#container {
width: 50%;
padding: 10px;
background: red;
#target {
position: relative;
width: 180%;
padding: 20px;
background: blue;
#inner {
padding: 10px;
background: gray;
}
#inner2 {
position: absolute;
top: 5px;
left: 5px;
width: 50px;
height: 150px;
background: yellow;
}
}
}
#ene {
position: absolute;
right: 30px;
top: 30px;
width: 100px;
height: 100px;
background: gray;
}
<div id="container">
<p id="target">
<span id="inner">hoge</span>
<span id="inner2">hoge2</span>
</p>
</div>
<div id="ene"></div>
<div id="log">--</div>
<div id="status"></div>
(function (win, doc, exports) {
'use strict';
var el = doc.getElementById('target');
/**
* Emulate mouse enter and leave.
* @constructor
* @param {Elemenet} el A target element.
* @param {string} eventName Watching event name.
* @param {Function} callback The callback.
*/
function EmulateLeaveEnter(el, eventName, callback) {
this.init.apply(this, arguments);
}
EmulateLeaveEnter.prototype = {
/**
* Initialize
* @param {Elemenet} el A target element.
* @param {string} eventName Watching event name.
* @param {Function} callback The callback.
*/
init: function (el, eventName, callback) {
this.el_ = el;
this.eventName_ = eventName;
this.callback_ = callback;
this.inFlg_ = false;
this.setOver_();
this.setOut_();
},
setOver_: function () {
var self = this,
el = this.el_;
el.addEventListener('mouseover', function (e) {
var desendants = [].slice.call(el.querySelectorAll('*'));
if (self.inFlg_) {
return true;
}
self.onEnter_(e);
}, false);
},
setOut_: function () {
var self = this,
el = this.el_;
el.addEventListener('mouseout', function (e) {
var desendants = [].slice.call(el.querySelectorAll('*')),
par = el.parentNode;
while (par) {
if (par === e.relatedTarget) {
self.onLeave_(e);
return true;
}
par = par.parentNode;
}
if (e.relatedTarget !== el && desendants.indexOf(e.relatedTarget) === -1) {
self.onLeave_(e);
}
}, false);
},
/**
* @param {Event} e Event object.
*/
onLeave_: function (e) {
this.inFlg_ = false;
this.fire_('leave', e);
},
/**
* @param {Event} e Event object.
*/
onEnter_: function (e) {
this.inFlg_ = true;
this.fire_('enter', e);
},
/**
* Fire the callback if eventType same this.eventName_.
* @param {string} eventType, The event type.
* @param {Event} e Event object.
*/
fire_: function (eventType, e) {
if (this.checkType_(eventType)) {
if (({}).toString.call(this.callback_) === '[object Function]') {
this.callback_(e);
}
}
},
/**
* @param {string} type The type.
* @return {boolean} return true if eventName_ is type.
*/
checkType_: function (type) {
if (this.eventName_ === type) {
return true;
}
return false;
}
};
EmulateLeaveEnter.prototype.constructor = EmulateLeaveEnter;
var evt = new EmulateLeaveEnter(el, 'enter', function (e) {
alert('Enter!');
});
var evt2 = new EmulateLeaveEnter(el, 'leave', function (e) {
alert('Leave!');
});
}(window, document, window));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment