0

Please see https://jsfiddle.net/cot33dxa/

setInterval(function() {
  if ($("#one").is(":hover")) {
    $("#one").css("background-color", "red");
  } else {
    $("#one").css("background-color", "");
  }
}, 0);

if ($("#two").is(":hover")) {
  $("#two").css("background-color", "blue");
} else {
  $("#two").css("background-color", "");
}
#one {
  width: 200px;
  height: 200px;
  background-color: yellow;
}
#two {
  width: 200px;
  height: 200px;
  background-color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div id="one"></div>
<div id="two"></div>

Why is it that for div one, the hover check works just fine, whereas it doesn't in div two?

I have the same issue when using if ($('#element:hover').length != 0) (taken from ivo's solution).

JS fiddle for that: https://jsfiddle.net/q8dfLc6s/

In a more general sense, I am looking for the simplest, most reliable way to know if the mouse is over a div in JQuery 1.11.0. As it stands, I can't even get the boolean check to work at all aside from this SetInterval oddity.

Community
  • 1
  • 1
ericgrosse
  • 1,490
  • 20
  • 37
  • 5
    Why are you using a setInterval instead of either the dom mouseover/enter/out/leave event ([jQuery hover](http://api.jquery.com/hover/)), or the :hover css pseudo class(if you are only needing this for doing styling)? – Patrick Evans May 11 '15 at 19:59
  • Post your code in your question please. – j08691 May 11 '15 at 20:01
  • Because it was used here in a similar question http://stackoverflow.com/a/8981521/2472351 I was trying to reverse engineer his solution and didn't understand why the boolean check would stop working once the setInterval function was factored out – ericgrosse May 11 '15 at 20:23

4 Answers4

2

The problem with your fiddle is that your second check is outside of your interval function. Try this:

setInterval(function(){
    if($("#one").is(":hover")) {
        $("#one").css("background-color","red");
    }
    else {
        $("#one").css("background-color","");
    }

    if($("#two").is(":hover")) {
        $("#two").css("background-color","blue");
    }
    else {
        $("#two").css("background-color","");
    }

},0);
Tatermelon
  • 489
  • 2
  • 10
  • But why do I need to use the interval function at all? If, for example, I use this boolean logic inside of a mouseclick event, I get the same problem. – ericgrosse May 11 '15 at 20:01
  • 1
    @Amalgam54 Inside a click event, you must be over the thing you're clicking on, so you can't be hovering over something else. – Barmar May 11 '15 at 20:03
  • Because the boolean logic only executes once. You need to use a mouseleave event like you were using in your other question. – Tatermelon May 11 '15 at 20:03
  • Oh it's not working in your event function? Can you post the code of your mouseclick event handler? – Tatermelon May 11 '15 at 20:05
  • @Tatermelon try https://jsfiddle.net/w953arn8/ , it only seems to work if you repeatedly move the mouse in and out of the div very quickly – ericgrosse May 11 '15 at 20:18
  • In that fiddle, the box turns red and stays red for me after I hover out of it the first time. Are you experiencing a different behavior? – Tatermelon May 11 '15 at 20:26
  • I just tried it in Chrome and got the same behavior as you. Seems to be an issue with Firefox (my version is 37.0.2). – ericgrosse May 11 '15 at 20:31
  • Oh that's strange. Firefox seems to trigger mouseleave slightly before hover is removed. Instead of an interval, you can slightly delay the check by ~50ms using setTimeout. – Tatermelon May 11 '15 at 20:36
1

The scond one doesn't work because it's not inside the interval timer and that code only runs on page load therefore

Change to

setInterval(function () {
    if ($("#one").is(":hover")) {
        $("#one").css("background-color", "red");
    } else {
        $("#one").css("background-color", "");
    }


    if ($("#two").is(":hover")) {
        $("#two").css("background-color", "blue");
    } else {
        $("#two").css("background-color", "");
    }

}, 0);

I have no idea why you need this and don't just use hover events or hover css

DEMO

charlietfl
  • 170,828
  • 13
  • 121
  • 150
1

Good question! By putting your code in a setInterval you are essentially mirroring what the browser is doing in the background in the event loop.

This behavior should generally be avoided and instead replaced by an actual event.

in jQuery this would look like:

$('#element').on( 'hover', function (this, event) {
    $element = this;
    /*handle event*/
});

More here: https://api.jquery.com/on/

Edit: The code you are running would be best done in CSS using the :hover selector as such:

#element {
    background-color: blue
}

#element:hover {
    background-color: red
}
lucky7id
  • 385
  • 1
  • 9
0

Instead of moving your code inside setInterval: the reason why your second example 'doesnt work', is the fact that it will execute only once the page has loaded. setInterval on the other hand, executes every ~0s which 'works'.

However to achieve what you're trying to do, consider to use .hover() as it is listening for the actual event of moving the cursor in or out of the selector and will not execute your else block all of the time:

$(function() {
    $("#two").hover(function() {
        $("#two").css("background-color","blue");
    }, function() {
        $("#two").css("background-color","");
    });
});

jsfiddle

The F
  • 3,647
  • 1
  • 20
  • 28