ArcBees / gwtquery

A jQuery clone for GWT, and much more.
MIT License
85 stars 38 forks source link

mouseleave & mouseenter fired twice #367

Open heyarny opened 8 years ago

heyarny commented 8 years ago

the events "mouseleave" and "mouseenter" are fired twice.

        $(element).mouseenter(new Function() {
            public boolean f(Event event, Object... obj) {
                // called twice...
                return true;
            }
        })

mouseout & mouseover are called just once as expected.

heyarny commented 8 years ago

oh, and not to mention, mouseenter & mouseleave do not behave in gwtquery like specified in jquery or elsewhere.

Please take a look at http://api.jquery.com/mouseover/

meriouma commented 8 years ago

Please explain a bit more what you mean by :

mouseenter & mouseleave do not behave in gwtquery like specified in jquery or elsewhere

heyarny commented 8 years ago

@meriouma

it should trigger only once as long you're within the node tree of the event holder. But gwtquery is triggering it every time you move to any child and back.

I have this simple example:

<style>
<!--
.test-box1 {
    position:relative;
    display:block;
    width:300px;
    height:300px;
    background:white;
}
.test-box2 {
    position:absolute;
    display:block;
    top:0;right:50px;bottom:50px;left:0px;
    background:blue;
    opacity:0.5;
}
.test-box3 {
    display:block;
    width:100px;
    height:100px;
    background:yellow;
}
-->
</style>

<div id="testbox" class="test-box1">
    <a href="javascript:;" class="test-box2">
        <span class="test-box3"></span>
    </a>
</div>
final Element testElm = $("#testbox").get(0);
$(testElm).on("mouseenter", new Function() {
            public boolean f(Event event, Object... obj) {
                Console.log("mouseenter");
                return true;
            }
        })
        .on("mouseleave", new Function() {
            public boolean f(Event event, Object... obj) {
                Console.log("mouseleave");
                return true;
            }
        });
heyarny commented 8 years ago

looks like the event is bound once as "mouseenter" and once again as "mouseover".. I guess you want to bind it ist once as "mouseover" and handle it with your MouseSpecialEvent you got there? At least that's what I think you wanted to do.

heyarny commented 8 years ago

As I found out the cause if this bug, I could create a workaround as long this bug exists.

        $(testElm).on("mouseenter", new Function() {
            public boolean f(Event event, Object... obj) {

                if (!event.getType().equals("mouseenter") || JsEventHelper.eventTriggeredByChilds(event)) {
                    return true;
                }

                QuickHelper.consoleLog("MOUSEENTER");

                return true;
            }
        })
        .on("mouseleave", new Function() {
            public boolean f(Event event, Object... obj) {

                if (!event.getType().equals("mouseleave") || JsEventHelper.eventTriggeredByChilds(event)) {
                    return true;
                }

                QuickHelper.consoleLog("MOUSELEAVE");

                return true;
            }
        });

Content of JsEventHelper.eventTriggeredByChilds(event):


    public static final boolean eventTriggeredByChilds(Event event) {
        Element eventTarget = event.getCurrentEventTarget().cast();
        Element currentTarget = event.getEventTarget().cast();
        return GQuery.contains(eventTarget, currentTarget);
    }

Note:

event.getType().equals("mouseleave");

To prevent further execution as gwtquery is trying to execute it once again as "mouseover". And eventTriggeredByChilds prevents further execution when reaching any of it's child elements.

Now it seems to work as intended. Hope this helps you to fix the issue.

meriouma commented 8 years ago

Thanks! We'll look into this.