Подозрительно этот код:
_getel(this.id).addEventListener('mouseover', this.displayPopup)
... потому что, хотя вы подключаете функцию как обработчик событий, вы ничего не делаете для сохранения значения this
внутри обработчика. Поэтому, когда вызывается обработчик, this
будет не таким же, как в коде выше. Я подозреваю, что эта потеря того, что означает this
, является причиной того эффекта, который вы видите, когда пытаетесь сделать это с более чем одним TimeBlock
экземпляром.
Существуют различные способы гарантировать, что ваши функции вызываются с правильным значением this
, один из которых выглядит следующим образом:
function TimeBlock(c, local_count){
/* creates a timeblock */
.
.
.
var self = this;
_getel(this.id).addEventListener('mouseover', function(event) {
self.displayPopup(event);
});
_getel(this.id).addEventListener('mouseout', function(event) {
self.killPopup(event);
});
}
Больше чтения:
Единственное, что приходит на ум, это то, что mouseover
и mouseout
пузырь для родительских элементов, что может сбить с толку, если вы не будете осторожны. Так, например, если у вас есть:
<div>Foo <span>bar</span></div>
... и вы наблюдаете за mouseover
и mouseout
на div
, вы увидите mouseout
, когда мышь переместится из span
("бар") в div
( "foo"), что может быть удивительно, если вы этого не ожидаете.
Вот пример, демонстрирующий два независимых экземпляра, подключенных к независимым элементам, как указано выше ( live copy ):
window.onload = function() {
new TimeBlock("firstElement");
new TimeBlock("secondElement");
function _getel(id) {
return document.getElementById(id);
}
function TimeBlock(id){
var self = this;
this.id = id;
this.counter = 0;
_getel(this.id).addEventListener('mouseover', function(event) {
self.displayPopup(event, this);
});
_getel(this.id).addEventListener('mouseout', function(event) {
self.killPopup(event, this);
});
}
TimeBlock.prototype.displayPopup = function(event, element) {
++this.counter;
element.innerHTML = "Display, counter = " + this.counter;
};
TimeBlock.prototype.killPopup = function(event, element) {
element.innerHTML = "Remove, counter = " + this.counter;
};
};