I have commented the relevant code. I found through trial and error that I have to use bind in both the event handler and the named callback in order for things to work correctly.
I did not find this intuitive as I thought that the named callback would call the function with a value of this pointing to the containing object literal.
I understand that the event handler needs a bind b.c. normally the callback would point to the element which triggered the event.
But the second bind, ( which I verified is required ), I don't understand the mechanism/concept.
There is a // *
denoting the area of focus.
NS.parsel({
Name: 'MSimMenu',
E: {
hold_name: '#hold_name',
wrap_bottom: '#wrap_bottom'
},
A: {
time_out_id: null,
TIME_DELAY: 1000
},
init: function () {
var self = this;
self.E.hold_name.addEventListener( "mouseover", self.mouseOverTop.bind(self), false);
self.E.wrap_bottom.addEventListener( "mouseover", self.mouseOverBottom.bind(self), false);
self.E.wrap_bottom.addEventListener( "mouseout", self.mouseOut.bind(self), false);
self.E.hold_name.addEventListener( "mouseout", self.mouseOut.bind(self), false);
},
// callbacks
mouseOverTop: function () {
NS.clearTimeout(this.A.time_out_id);
this.showBottom();
},
mouseOverBottom: function () {
NS.clearTimeout(this.A.time_out_id);
},
mouseOut: function () {
// * this regards the question
// bind is required here for hideBottom to have correct value of this
this.A.time_out_id = NS.setTimeout(this.hideBottom.bind(this), this.A.TIME_DELAY);
},
// called from callbacks
showBottom: function () {
this.E.wrap_bottom.style.visibility = 'visible';
},
hideBottom: function () {
this.E.wrap_bottom.style.visibility = 'hidden';
}
});