jQuery mouseleave not firing correctly while dragging
Asked Answered
C

1

9

I have a sortable list with a mouseleave event listener that is behaving incorrectly.

If I move the mouse in and out of the sortable list, mouseleave fires correctly.

If I first click and drag one of the sortable's children, mouseleave fires incorrectly - sporadically or not at all.

Any ideas?

Thanks.

update: This occurs for mouseout events as well.

<style>
#sortable { list-style-type: none; margin: 0; padding: 0; float: left; margin-right: 10px; background-color: #CCC; }

#sortable li { margin: 0 5px 5px 5px; padding: 5px; font-size: 1.2em; width: 120px; }
</style>

<script>
  $(function(){
    $("#sortable").sortable().disableSelection();
    $("#sortable").mouseleave(function(){ console.log("mouseleave"); });
  });   
</script>

<ul id="sortable">
  <li class="ui-state-default">Item 1</li>
  <li class="ui-state-default">Item 2</li>
  <li class="ui-state-default">Item 3</li>
</ul>

update I have used the following to detect when a child has been dragged fully outside of the sortable:

$("#sortable li").mousemove(function() {
        if ($(this).offset().left > $(this).parent().outerWidth() + $(this).parent().offset().left ||
                $(this).offset().top > $(this).parent().outerHeight() + $(this).parent().offset().top  ||
                $(this).offset().left + $(this).outerWidth() < $(this).parent().offset().left  ||
                $(this).offset().top + $(this).outerHeight() < $(this).parent().offset().top ){
                console.log("child is outside parent");
            }
    });
Cantus answered 22/7, 2011 at 3:24 Comment(6)
Have you tried mouseout?Matisse
@Matisse - i tried - same result.Sketchy
It's worth noting if I instead add a mouseout event listener with document.getElementById("sortable").addEventListener("mouseout", onmouseout, false);, I get the same behavior.Cantus
@Cantus you get that same behavior because behind the scenes that is what jQuery is doing for you.Endear
Shouldn't you use dragleave for that?Metropolitan
@Metropolitan I believe that I should be using the sortable "out" event, but it wasn't firing as expected, which lead me to try mouseleave.Cantus
E
5

I'm going to make an assumption and say that you are trying to capture the event when the element visually leaves the sortable area. As you found out, mouseleave and mouseout are not the best ways to do that because they track mouse movement relative to the DOM elements. Since you are dragging these list items they never actually leave the unordered list so you aren't getting the results you expect.

This however should work for you:

$("#sortable").sortable().disableSelection();
$("#sortable li").mousemove(function() {
    if (parseInt($(this).css("left")) > $("#sortable").width() ||
        parseInt($(this).css("top")) > $("#sortable").height()) {
        //This is when the element is out of bounds
    }
});
Endear answered 22/7, 2011 at 5:17 Comment(3)
Thanks. I am trying to capture the event when the mouse visually leaves the sorting area, moreso than the child elements. Are you saying that, when dragging a child, even though the child (and mouse) may visually be outside the parent, no mouseout event should fire because according to the dom the mouse never left the parent?Cantus
@Cantus - That is correct. Because you want to judge whether or not it is outside of the parent visually you will have to look at the height and width of the parent and determine based on the childs position whether the child is outside of the parent. This is what my code above does.Endear
Very interesting, thank you for pointing that out! It really does make logical sense from the perspective of the DOM, but it hadn't occurred to me what was happening. I have used what you suggested, and adapted it to my needs (above).Cantus

© 2022 - 2024 — McMap. All rights reserved.