Question

Not sure how to go about this, but basically I wrote a tooltip plugin which removes the tooltips on either mouseout or mousedown.

If a mousedown event is triggered, it'll remove $that.parent() which is fine, and this removes the tooltip, but then if the user also triggers the mouseout event (which they will because the mouseover and mouseout events are currently chained), it will then delete another DOM element which I don't want. So essentially I'm wondering if this is possible:

$that.on('mouseover', function() {

    // If this event is triggered within the mouseover event, don't run the chained mouseout event
    $that.on('mousedown', function() {
        $that.parent().next().fadeOut(100).remove();
        return false;
    });
}).mouseout(function() {
  // If they clicked above, don't run this
    $that.parent().next().fadeOut(100).remove();
});​

As far as I know, without using a global variable it's hard to access a clicked boolean set inside of that mousedown event e.g:

$that.on('mouseover', function() {
    clicked = false;
    // If this event is triggered within the mouseover event, don't run the chained mouseout event
    $that.on('mousedown', function() {
        clicked = true;
        $that.parent().next().fadeOut(100).remove();
        return false;
    });
}).mouseout(function() {
    // If they clicked above, don't run this
    if (clicked) {
        $that.parent().next().fadeOut(100).remove();
    }
});​

Any thoughts on how to construct this elegantly?

EDIT: The elements in $that.parent().next() are just a <div class="js-tooltip"><span>Tooltip text</span></div>

But this should be irrelevant as I'd like to just know if it's possible to return from that mouseover function if the mousedown was triggered without using a global variable.

Was it helpful?

Solution

Have you considered simply using the class filter like this?

$that.parent().next('.js-tooltip').fadeOut(100).remove();

This would simply not do anything if the next wasn't a tooltip, which should solve the problem as far as I understand.

Using your proposed method, it would be clearner to do $that.clicked = false.

Alternatively how about (if you want to keep the mouseover at all - this is just to demonstrate the principle; I'm not sure if it would work like this):

$that.on('mouseover', function() {

    // If this event is triggered within the mouseover event, don't run the chained mouseout event
    $that.on('mousedown mouseout', function() {
        $that.parent().next().fadeOut(100).remove();
        $that.off('mousedown mouseout'); //prevent that happening again
        return false;
    });
});

OTHER TIPS

You don't need the mouseover.

$that.on('mouseleave mouseup', function(e) {
     if( e.type === 'mouseleave'){
         // do the mouseleave stuff
     }else{
         // do the mouseup stuff
     }
});​

As you said, if the elements is dynamically created you should use:

$(document).on('mouseleave mouseup', $that, function(e) {

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top