mouseenter & mouseleave: tooltip not hiding

21 views
Skip to first unread message

Kupido

unread,
Oct 30, 2009, 5:51:29 AM10/30/09
to Prototype & script.aculo.us
Hi all,
I have a page with some boxes placed side by side. When the user moves
over one of them a tooltip appears, then it should disappear when the
user moves out or moves over another box.

I use the mouseenter and mouseleave events to do this but sometimes,
when the user moves quickly on the boxes, some tooltips don't hide. I
can see even more than one tooltip at the same time and they won't
disappear until the boxes are hovered again. It's like the mouseleave
event is not triggered, but if I put an alert in it I see it gets
triggered.

The code is the following:

$('boxes').select('.box').each(
function (element)
{
Event.observe(element, 'mouseenter', mouseEnter.bindAsEventListener
(element));
Event.observe(element, 'mouseleave', mouseLeave.bindAsEventListener
(element));
}
);

function mouseEnter(event, element)
{
...
}

function mouseLeave(event, element)
{
...
}

What am I doing wrong? Any help would be appreciated, thanks in
advance.

david

unread,
Oct 30, 2009, 6:03:42 AM10/30/09
to Prototype & script.aculo.us
Hi Kupido,

When writting:
Event.observe(element, 'mouseenter', mouseEnter.bindAsEventListener
(element));

When writting "bindAsEventListener", it means that your binded
function will have its scope set to element.
So your called fiunction should be:
function mouseEnter(event)
{
this.setStyle('color:blue'); //just an exemple of a call to an
element method.

}

In your writting, there is an element argument. If you use it, I'm not
sure it works.

Btw, if you can post your whole code, it could help us.

--
david

Kupido

unread,
Oct 30, 2009, 6:37:50 AM10/30/09
to Prototype & script.aculo.us
Hi david, thank you for your reply.

The element argument in my previous post was a copy/paste error,
here's a simplified working version of my code:

function init()
{
var boxes = $('boxes');

boxes.select('.box').each(
function (box)
{
Event.observe(box, 'mouseenter', mouseEnter.bindAsEventListener
(box, box.down('.tooltip')));
Event.observe(box, 'mouseleave', mouseLeave.bindAsEventListener
(boxes));
}
);

function mouseEnter(event, tooltip)
{
if (!tooltip.visible())
{
tooltip.setStyle({
top: (this.positionedOffset().top + this.getHeight() + 10) + 'px',
left: (this.positionedOffset().left) + 'px'
});
tooltip.show();
}
}

function mouseLeave(event)
{
this.select('.tooltip').invoke('hide');
}
}

document.observe('dom:loaded', function () { init(); });
Message has been deleted

Kupido

unread,
Oct 30, 2009, 7:18:59 AM10/30/09
to Prototype & script.aculo.us
After some testing I noticed the problem only occurs when I use:

tooltip.appear(); // scriptaculous effect

instead of:

tooltip.show();

Any suggestions?

david

unread,
Oct 30, 2009, 7:55:28 AM10/30/09
to Prototype & script.aculo.us
Hi Kupido,

the mouseleave event is a hide which set display property to none;
And the mouseenter event is an appear, which set opacity from 0 to 1.

So when the element is hide, there is no way to appear again, because
they don't change the same property.
This could explain why event is still triggered, but you'll see
nothing.

One note about using event on mouseeneter/mouseleave (like mouseover/
mouseout):
you 'll need to save the effect in execution so if you want to launch
the opposite effect and the executed effect is not finished, you could
cancel() executing effect and after launch the opposite (new) effect.
Otherwise it will flicker !

--
david

Kupido

unread,
Oct 30, 2009, 7:58:27 AM10/30/09
to Prototype & script.aculo.us
I think I solved the problem using effect queues, this is the new
code:



function init()
{
var boxes = $('boxes');

boxes.select('.box').each(
function (box)
{
var tooltip = box.down('.tooltip');

Event.observe(box, 'mouseenter', mouseEnter.bindAsEventListener
(box, tooltip));
Event.observe(box, 'mouseleave', mouseLeave.bindAsEventListener
(box, tooltip));
}
);

function mouseEnter(event, tooltip)
{
if (!tooltip.visible())
{
tooltip.setStyle({
top: (this.positionedOffset().top + this.getHeight() - 20) + 'px',
left: (this.positionedOffset().left + parseInt(this.getWidth() /
2)) + 'px'
});
tooltip.appear({ duration: 0.2, to: 0.8, queue: { position: 'end',
scope: 'boxes-scope', limit: 1 }});
}
}

function mouseLeave(event, tooltip)
{
Effect.Queues.get('boxes-scope').invoke('cancel');

tooltip.hide();
}
}

document.observe('dom:loaded', function () { init(); });



Comments and suggestions are welcome!

david

unread,
Oct 30, 2009, 8:02:08 AM10/30/09
to Prototype & script.aculo.us
Hi Kupido,

This is a good way to do this.
Just a suggestion, if the tooltip appear, let it des-appear sloowly
too.
so don't just hide() it, but do an effect to do this :))

--
david

Kupido

unread,
Oct 30, 2009, 8:05:30 AM10/30/09
to Prototype & script.aculo.us
Hi david,
I'll consider using fade instead of hide, thank you again for your
help!
Reply all
Reply to author
Forward
0 new messages