16

without jquery

basically what I am looking for is the ability to see if the mouse is over a div when a countdown finishes

if the user is over the div then perform action for that div

onmouseover only triggers when the mouse crosses the threshold of the div, if the mouse hasn't moved it wouldn't trigger, so that wouldn't work

I need to determine if the mouse is currently over a div at a specific point in time, if it has moved or not from the starting point

all of my hunting has only found onmousover, and nothing to see if the mouse just happens to be there to begin with

I don't have the javascript skills to determine overall coords of div, then map mouse coords and see if it fits there... which is what I believe I need to do

Kender
  • 1,191
  • 3
  • 15
  • 34
  • Calculating the actual coordinates of your box and doing the bounds checks will be tough, and will rely on mouse events anyways to get the mouse's current coordinates. Tracking mouseover/mouseouts has the issues you mentioned. I'm experimenting with detecting CSS :hover styles, which may be more reliable. I'll post a fiddle if it works. – George Aug 19 '13 at 18:09
  • Also see: [How to get the mouse position without events (without moving the mouse)?](http://stackoverflow.com/questions/2601097/how-to-get-the-mouse-position-without-events-without-moving-the-mouse) – rink.attendant.6 Aug 19 '13 at 18:31
  • @ScottMermelstein How do you force the document to fire a click event at the current coordinates? I only found a way to fire click events using custom/specified coordinates. – rink.attendant.6 Aug 19 '13 at 18:58
  • @rink.attendant.6 Drat, you're right. In testing, I got body.click() to fire an event (figured I'd start with jQuery and work my way back), but it always reported 0,0 as the coordinates. I take back my suggestion. – Scott Mermelstein Aug 19 '13 at 19:21
  • I was just thinking about this, and had an idea (as of yet untested, may do so later)... onmouseenter and onmouseleave trigger when the mouse crosses the boundary... comes the question of "what if it's not the mouse that changes that relation, but the div?" I'm thinking of having an invisible 1px height 100% width div cycling vertically along the page and triggering on mouse location. Wouldn't even need js for anything before trigger, just an animation that moves 0 to 100 vh and back. Similarly, have a 1px wide and 100% height animating across vw, and you can repeatedly pinpoint mouse, maybe? – lilHar Dec 01 '15 at 15:21

6 Answers6

16

After reading the second answer (the one with millions of a elements) on this SO question, I've came up with this method works without moving the mouse on page load, without involving millions of elements.

HTML

<div id=t></div>

CSS

#t {
    /* for illustrative purposes */
    width: 10em;
    height: 5em;
    background-color: #0af;
}
#t:hover {
    border-top-style: hidden;
}

JavaScript

document.addEventListener('click', function () {
    var c = window.getComputedStyle(document.getElementById('t')).getPropertyValue('border-top-style');

    if (c === 'hidden') {
        alert('Mouse in box');
    } else {
        alert('Mouse not in box');
    }
}, false);

As stated earlier, bind to the finish event of your countdown instead of the click event on the document.

You may also use any CSS style that's changed on :hover, I chose border-top-style as it is conspicuous. If you're using a border, choose something else.

Here's a jsFiddle.

Community
  • 1
  • 1
rink.attendant.6
  • 44,500
  • 61
  • 101
  • 156
  • OMG so funny and tricky way to do it without invoking any "clientX" nor "mouse" event ! You use the native "hover" to trick it. I'm sure it's the lightest solution in this thread. Anyway, so funny, you deserve more upvotes ! – lapin Feb 03 '16 at 08:54
  • This is total awesomeness. Cheers! – Figaro Cat Sep 23 '19 at 07:39
10

set a flag to true onmouseover and to false onmouseleave. when countdown finishes if flag is true then it is over element.

HTML

<div id="div-name">the section of the code i am working with has a countdown timer, when it reaches 0 i need to know if the mouse is over a specific box</div>
<button id="notification" onclick="javascript: letsCountIt(5);">click to start countdown</button>

JS

window.ev = false;

document.getElementById('div-name').onmouseover = function () {
    window.ev = true;
    console.log(window.ev);
}

document.getElementById('div-name').onmouseout = function () {
    window.ev = false;
    console.log(window.ev);
}

window.letsCountIt = function (cdtimer) {
    cdtimer--;
    document.getElementById('notification').innerHTML = cdtimer;

    if (cdtimer == 0) {
        if (window.ev === true) {
            alert('over');
        } else {
            alert('not over');
        }
    } else {
        setTimeout(function(){letsCountIt(cdtimer);}, 1000);
    }
}
km6zla
  • 4,787
  • 2
  • 29
  • 51
  • 1
    Kender's question is how to handle the case that the mouse does not move to produce either of those events. Imagine the mouse is positioned over the box before page load and the mouse never moves before the countdown ends. – George Aug 19 '13 at 18:17
  • 1
    @George onmouseover would inevitably trigger. see http://jsfiddle.net/dbaqY/. put mouse on output then hit ctrl+enter. – km6zla Aug 19 '13 at 18:26
  • thank you George P, for pointing out the flaw, while the flag is a good idea, it would not work in this case – Kender Aug 19 '13 at 18:27
  • @Kender Yes it would, see fiddle. Onmouseover triggers even if mouse is there to begin with. – km6zla Aug 19 '13 at 18:28
  • @ogc-nick Does not work for me in the latest Chrome. I don't get a dialog box until I move my mouse. – George Aug 19 '13 at 18:28
  • @George Interesting because I too have latest chrome and it does work. – km6zla Aug 19 '13 at 18:30
  • @ogc-nick, it does work in my newest chrome, also in firefox... great how can I convert this to a `if/else` statement to fire event a or b? – Kender Aug 19 '13 at 18:48
  • tried several methods `document.getElementById('div-name').onmouseover = function() { window.ev = 1; }` setting this, with `if(window.ev != 1)` then `delete window.ev` at the end of the segment of code, among them... please, any help would be appreciated – Kender Aug 19 '13 at 20:50
  • @Kender make a jsfiddle and I will help you with it. Or use mine as a starting point jsfiddle.net/dbaqY. – km6zla Aug 19 '13 at 22:39
  • 1
    You almost had it. See this: http://jsfiddle.net/7R8em/. And I will update my answer. – km6zla Aug 20 '13 at 15:37
  • That is actually perferct, I did a little tweaking and it works awesomely (I was trying to keep the defining of `window.ev` within the function and just had to move it outside of it! Thanks a ton. – Kender Aug 20 '13 at 16:27
2

Look into document.elementFromPoint . When you pass an x,y to elementFromPoint, it will return whatever element (or <body>, if no other specific element) is at that point. You can easily check if this element is the element you want.

The problem then is finding out what point your mouse is at. How to get the mouse position without events (without moving the mouse)? seems to say - don't. At least use mouseMove to track the cursor. The linked question gives examples of how to do so. (Look to the lower scoring answers, as the higher ones only got points for being snarky.)

Community
  • 1
  • 1
Scott Mermelstein
  • 15,174
  • 4
  • 48
  • 76
1

Just want to say that, I think jQuery's mouseenter and mouseleave events would make this a lot easier, but if you can't use them, maybe this will help you.

Depending on how your page is laid out, this may not be too difficult. You can get the position of your element using the following. Quoting from another answer

element.offsetLeft and element.offsetTop are the pure javascript properties for finding an element's position with respect to its offsetParent; being the nearest parent element with a position of relative or absolute

So, if your element is positioned relatively to the body, so far so good (We don't need to adjust anything).

Now, if we attach an event to the document mousemove event, we can get the current coordinates of the mouse:

document.addEventListener('mousemove', function (e) {
    var x = e.clientX;
    var y = e.clientY;
}, false);

Now we just need to determine if the mouse falls within the element. To do that we need the height and width of the element. Quoting from another answer

You should use the .offsetWidth and .offsetHeight properties. Note they belong to the element, not .style.

For example:

var element = document.getElementById('element');
var height = element.offsetHeight;
var width = element.offsetWidth;

Now we have all the information we need, and just need to determine if the mouse falls within the element. We might use something like this:

var onmove = function(e) {
   var minX = element.offsetLeft;
   var maxX = minX + element.offsetWidth;
   var minY = element.offsetTop;
   var maxY = minY + element.offsetHeight;

   if(e.clientX >= minX && e.clientX <= maxX)
       //good horizontally

   if(e.clientY >= minY && e.clientY <= maxY)
       //good vertically
}
Community
  • 1
  • 1
Tim Mac
  • 1,149
  • 1
  • 8
  • 17
  • unfortunately there is no guarantee the mouse will move at all :( I am trying to establish if the mouse is over an element, possibly when the page loads, without motion – Kender Aug 19 '13 at 18:29
  • true, just thought the same thing as I was re-reading the question. There's no way to detect the mouse position without an event http://stackoverflow.com/a/2601273/1167867 – Tim Mac Aug 19 '13 at 18:30
  • thanks for the effort! I like the long answer to the question linked – Kender Aug 19 '13 at 18:34
0

This code works, but the mouse has to be moved once after page load.

var coords;
var getMouseCoordinates = function (e) {
    'use strict';
    return {
        x: e.clientX,
        y: e.clientY
    };
};

document.addEventListener('mousemove', function (e) {
    coords = getMouseCoordinates(e);
}, false);

document.addEventListener('click', function () {
    var divCoords = document.getElementById('t').getBoundingClientRect();

    if (coords.x >= divCoords.left && coords.x <= divCoords.right && coords.y >= divCoords.top && coords.y <= divCoords.bottom) {
        alert('Mouse in box');
    } else {
        alert('Mouse not in box');
    }
}, false);

You wouldn't bind to the click event of document, but rather the finish event of your countdown.

Here's an example. Try clicking in the output window.

rink.attendant.6
  • 44,500
  • 61
  • 101
  • 156
0

You don't need any coordinates or mouse events, if you know a selector for that element:

if (document.querySelector('#elementSelector:hover')) {
    alert('I like it when you touch me!');
}
Serban Stokker
  • 121
  • 1
  • 5