Вот рабочая версия, более или менее. При создании элементов мы прикрепляем событие mouseover
:
var self = this;
SimileAjax.DOM.registerEvent(labelElmtData.elmt, "mouseover", function (elt, domEvt, target) {
return self._onHover(labelElmtData.elmt, domEvt, evt);
});
Вызывает функцию, которая устанавливает тайм-аут (ранее существующие таймауты для другого элемента отменяются):
MyPlan.EventPainter.prototype._onHover = function(target, domEvt, evt) {
... calculate x and y ...
domEvt.cancelBubble = true;
SimileAjax.DOM.cancelEvent(domEvt);
this._futureShowBubble(x, y, evt);
return false;
}
MyPlan.EventPainter.prototype._futureShowBubble = function (x, y, evt) {
if (this._futurePopup) {
if (evt.getID() == this._futurePopup.evt.getID()) {
return;
} else {
/* We had queued a different event's pop-up; this must now be cancelled. */
window.clearTimeout(this._futurePopup.timeoutID);
}
}
this._futurePopup = {
x: x,
y: y,
evt: evt
};
var self = this;
this._futurePopup.timeoutID = window.setTimeout(function () {
self._onTimeout();
}, this._popupTimeout);
}
Это в свою очередь показывает пузырь, если он выстрелил до того, как был отменен:
MyPlan.EventPainter.prototype._onTimeout = function () {
this._showBubble(this._futurePopup.x, this._futurePopup.y, this._futurePopup.evt);
};
MyPlan.EventPainter.prototype._showBubble = function(x, y, evt) {
if (this._futurePopup) {
window.clearTimeout(this._futurePopup.timeoutID);
this._futurePopup = null;
}
...
SimileAjax.WindowManager.cancelPopups();
SimileAjax.Graphics.createBubbleForContentAndPoint(...);
};
Кажется, теперь это работает. Я установил тайм-аут на 200 мс, а не на 100 мс. Не знаю, почему слишком короткое время ожидания приводит к возникновению многопузырьковой ситуации, но я предполагаю, что очереди оконных событий или что-то еще может происходить, пока выкладываются новые элементы.