Search code examples
javascriptjquerycssmouseovermouseout

Javascript - Issue with mouse events and floating element


I've got a tricky problem with a script I'm writing using jQuery.

I have a table which will have a toolbar appear on any row if hovered over (except the heading row). This is working great, and this is the code for it:

$cont.delegate('tr:not(:eq(0))','mouseover mouseout', function(e){
    var $this = $(this);
    var pos = $this.position();
    if(e.type == 'mouseout') {
        $actionToolbar.hide();
    } else {
        $actionToolbar.css({
            'top'  : pos.top  + $this.height()/2 - $actionToolbar.height()/2,
            'left' : pos.left + $this.width()    - $actionToolbar.width()
        }).show();
    }
});

The problem arises when I hover over the action toolbar. The row's mouseout event fires, and the toolbar hides (then enters an infinite loop of showing/hiding). This is because the toolbar is absolutely positioned and not a child of the row.

Here's the deal:

  • I do not want it to be a child of the row, because that means I'd have to remove and append to the DOM for every mouse event -- and this is not as efficient as simply updating the element's CSS.
  • I would also like to avoid timers to solve this if possible.

Thanks in advance!


Solution

  • Having little patience, I've gone and found my own answer:

    I've removed the mouseout event listener and moved to using jQuery's data() method to keep track of the previously hovered row. Then, I add a mouseleave event listener to the container.

    It works perfectly:

    $cont.delegate('tr:not(:eq(0))', 'mouseover', function(e) {
        var $this = $(this);
        $($cont.data('COLStorage.row')).removeClass(opts.hoverClass);
        $this.addClass(opts.hoverClass);
        var pos = $this.position();
        $actionToolbar.css({
            'top': pos.top + $this.height() / 2 - $actionToolbar.height() / 2,
            'left': pos.left + $this.width() - $actionToolbar.width()
        }).show();
        $cont.data('COLStorage.row', $this);
    }).mouseleave(function(e) {
        $actionToolbar.fadeOut();
    });