Search code examples
jquerytriggersmouseoverchildrenmouseout

Jquery mouseover/mouseout triggering inconsistently


I have two sortable lists, one being nested, with a mouse over effect on the li elements of the nested sortable list. My problem is that the mouseover and mouseout functions are being called inconsistently when a user moves the mouse quickly through the list over the child elements.

Here is a sample of what is happening, you have to drag a pane into the list and then drag 3-4 textbox items into the pane to be able to see the problem. You can see the 2 numbers in the top right are keeping track of the in/out of the mouse. Note I have only tested my site in firefox thus far.

example

My jquery code:

Here are the mouseover and mouseout functions:


$(".pane > li").live("mouseover", function(){
    $("#in").html(in1);
    $(this).children(".test").stop().animate({opacity: 1},400);
    in1++;
});

$(".pane > li").live("mouseout", function(){ $("#out").html(out1); $(this).children(".test").stop().animate({opacity: 0},400); out1++; });

$(".pane > li > *").live("mouseover", function(event){ event.stopPropagation(); });

$(".pane > li > *").live("mouseout", function(event){ event.stopPropagation(); });

The first sortable list:


    var counter = 0;
    var height="";
    var in1 =0;
    var out1=0;

$("#left-form-space").sortable({

update: function(ev, ui){ if (!ui.item.is('.noChange')){ addNewPane(ui.item); } }, start: function(event, ui){ if (ui.item.is('.noChange')){ $("#left-form-space").css({'height' : height}); $("#left-form-space").animate({height: "75px"}, 600, function(){ $("#left-form-space").css({'height' : 'auto'}); }); } }, stop: function(event, ui){ $item = ui.item; if ($item.is('.noChange')){ $item.css({'height' : '0px'}); $item.animate({height: "150px"}, 600, function(){ $item.css({'height' : 'auto'}); }); } }, placeholder: '.placeholder-highlight', cursor: 'move', revert: true });

$("ul, li").disableSelection();

My function for adding the nested sortable lists:


function addNewPane($item){
    counter++;
    var newID = "pane_" + counter;
    $item.attr("id", newID);

$item.html('').animate({height: "150px"}, 600, function(){
    $item.css({'height' : 'auto'});
    $item.html('<fieldset class="sortable-pane"><div class="pane-nav"><a href="link/to/recycle/script/when/we/have/js/off" title="Delete this image" class="ui-icon ui-icon-close">Delete image</a></div><ul class="pane"></ul></fieldset>');
    $("#" + newID + " > fieldset").hide().fadeIn('slow');
    $(".pane").sortable({
        placeholder: 'ui-state-highlight',
        update: function (event, ui){
            if (!ui.item.is('.noChange')){
                if (ui.item.is('.textbox')){
                    $(ui.item).html('<div class="test ui-corner-tl ui-corner-bl">test</div><input class="label" value="First Name:"/><input name="input1" id="input1" type="text" /><div id="spacer"></div>');

                }
                if (ui.item.is('.header')){
                    $(ui.item).html('<div id="element2" class="element header"><h1>Contact Information</h1></div>');
                }
            }
        },
        cursor: 'move',
        revert: true
    });

    var newFormHeight = $("#left-form-space").height() + "px";
    height=newFormHeight;
    $item.addClass('noChange');
});

};

Thanks for any assistance.


Solution

  • I haven't looked at all your code but I did notice that when you add new [panes] you also attach events.

    What might be better is if you use the live keyword as this will ensure all elements with a given id / class etc have the events attached automatically when you add the element.

    So if you add code like this;

    $('.MyPanels').live("mouseover", function() { //do stuff });
    

    Then everytime you add an element that contains a class name of 'MyPanels', the mouseover event will be attached to it.

    This I find saves a lot of confusion in that you can never add two mouse events to an element and I also no longer need to specifically code for it.

    Unsure if this fixes your problem but it would certainly tidy things up and may fix or expose where the issue is.