我已经评论了相关代码。我通过反复试验发现,我必须在事件处理程序和命名回调中都使用 bind 才能使事情正常工作。
我没有发现这很直观,因为我认为命名回调会调用函数,其值 this 指向包含对象字面量。
我知道事件处理程序需要绑定 bc 通常回调将指向触发事件的元素。
但是第二个绑定(我验证是必需的),我不了解机制/概念。
有一个// *
表示焦点区域。
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';
}
});