1

Please see this fiddle

Ignore CSS, its not important.

The purpose of this jQuery code is to tell the direction opposite to the direction from which mouse entered inside the .container. I know its an ugly looking function but please ignore that for a while. The direction is in terms of n (for north), ne (for north-east), and so on ...

Now if you open the console and move the mouse around the div.container like a maniac, eventually you will see undefined in the console. (div.container is invisible and surrounds the circular button)

Value undefined is only possible if x === 0 && y === 0 in getMovementDirection(), which means that mouse on entering the div.container was inside the div.button (spherical button), which is not possible.

So, my question is, what's going on in that code?

-Thanks for help

PS: Title needs improvement.

jQuery code

(function($) {
    var $container = $('div.container'),
        $button = $('div.button');

    $container.on('mouseenter', function(e) {
        var mouseLocation = {
            x: e.pageX,
            y: e.pageY
        }
        var buttonLocation = {
            x: $button.offset().left,
            y: $button.offset().top
        }

        var loc = getMovementDirection (mouseLocation, buttonLocation, jQuery);
        console.log(loc);
    });
})(jQuery);

function getMovementDirection (mouse, container, $) {
    var width = $('div.button').outerWidth(),
        height = $('div.button').outerHeight();
    var x, y;

    if (mouse.x < container.x) { x = -1; }
    else if (mouse.x < container.x + width) { x = 0; }
    else { x = 1; }

    if (mouse.y < container.y)  { y = -1; }
    else if (mouse.y < container.y + width) { y = 0; }
    else { y = 1; }

         if ( x === -1 && y === -1 ) { return 'se'; }
    else if ( x ===  0 && y === -1 ) { return 's';  }
    else if ( x ===  1 && y === -1 ) { return 'sw'; }
    else if ( x === -1 && y ===  0 ) { return 'e';  }
    // x === 0 && y === 0 is forbidden
    else if ( x ===  1 && y ===  0 ) { return 'w';  }
    else if ( x === -1 && y ===  1 ) { return 'ne'; }
    else if ( x ===  0 && y ===  1 ) { return 'n';  }
    else if ( x ===  1 && y ===  1 ) { return 'nw'; }
}
Community
  • 1
  • 1
Sourabh
  • 8,243
  • 10
  • 52
  • 98
  • this has nothing to do with the issue, but you are checking the mouse.y against container.y + width instead of container.y + height. The only thing i can think of is the slight delay from the time the event gets triggered and where your mouse is when it captures the mouse location data. perhaps come up with a case for if someone has an epileptic seizure on your page and do something else with the button in that case? :\ – Kevin Nacios Jun 02 '13 at 04:45
  • Actually I was planning on making that mini-game where you try to click a button and it keeps on running away. I know jQuery is not best for it but it was just for fun. But this time delay thing, if true, ruined all my plans :( PS: container width = height in this case, but thanks for correcting me, I forgot to change that – Sourabh Jun 02 '13 at 04:56

1 Answers1

1

this might not be the most elegant solution or even the fix, but I updated the fiddle with a different way of getting the mouse data:

http://jsfiddle.net/e3XNm/3/

it doesnt use the jquery built in mouseenter event, but rather the js native mouseover event, and it ignores when mouseover is of the button. I figured there might be some extra overhead with how jquery is doing it (i didnt look at the code for it at all), so why not trim it down a bit to something more basic. also, i stole the addevent code from here: http://ejohn.org/projects/flexible-javascript-events/

addEvent( $container[0], 'mouseover', function (e) {
    if (e.target === $button[0])
        return;

    // get event details here

    var loc = getMovementDirection(mouseLocation, buttonLocation, jQuery);

    // debugging
    if (loc != undefined) {
        var width = $('div.button').outerWidth(),
            height = $('div.button').outerHeight();
        console.log(mouseLocation.x, mouseLocation.y, buttonLocation.x, buttonLocation.y, width, height);
        console.log(loc);
    } else {
        console.log("wut");            
    }

i couldnt get "wut" to be fired at all, but maybe im just not twitchy enough

Update

This is the jquery code that runs on every mouseover to execute the mouseenter behavior

// Create mouseenter/leave events using mouseover/out and event-time checks
jQuery.each({
    mouseenter: "mouseover",
    mouseleave: "mouseout"
}, function( orig, fix ) {
    jQuery.event.special[ orig ] = {
        delegateType: fix,
        bindType: fix,

        handle: function( event ) {
            var ret,
                target = this,
                related = event.relatedTarget,
                handleObj = event.handleObj;

            // For mousenter/leave call the handler if related is outside the target.
            // NB: No relatedTarget if the mouse left/entered the browser window
            if ( !related || (related !== target && !jQuery.contains( target, related )) ) {
                event.type = handleObj.origType;
                ret = handleObj.handler.apply( this, arguments );
                event.type = fix;
            }
            return ret;
        }
    };
});

Some delay may be occurring if its rerunning some handling code on a different element.

Kevin Nacios
  • 2,843
  • 19
  • 31
  • `Wut` wasn't fired because you added this: `if (e.target === $button[0]) return;`. If it was a case when `wut` was supposed to fire, return call was initiated. When I removed it, I was able to get `wut` fired – Sourabh Jun 02 '13 at 20:54
  • See [**this**](http://stackoverflow.com/questions/7448468/why-cant-i-reliably-capture-a-mouseout-event), [**this**](http://stackoverflow.com/questions/2597832/javascript-mouse-event-not-captured-properly-when-mouse-moved-very-fast) and [**this**](http://stackoverflow.com/questions/8823041/how-can-i-reduce-slowdowns-from-mousemove-event). It looks like no one has a solution. – Sourabh Jun 02 '13 at 21:10
  • i added the if statement because you dont care if the mouse is over button, you only care where it is when it enters container. mouseover fires when it goes over any element contained in parent. what this code does is only checks for position when the element that fired the event is container. – Kevin Nacios Jun 02 '13 at 21:40
  • Oh ok, I get it now. By bad. Is there any way to ignore the case when mouse goes from button to container? – Sourabh Jun 02 '13 at 21:47
  • check the event for the fromElement, if its button, just return - `if (e.target === $button[0] || e.fromElement === $button[0]) return;` – Kevin Nacios Jun 02 '13 at 22:39
  • Thanks that works. I'll post link to my `click it` game when and if it gets done – Sourabh Jun 03 '13 at 00:15
  • look forward to checking it out. glad i could help – Kevin Nacios Jun 03 '13 at 00:23