Getting mouse position in keyboard event


I'm trying to have a selection wheel appear when the user holds down the Shift key.

The wheel should be centred on the mouse's position.

However when I test this, pageX and clientX are both undefined on the event object.

Is it possible to get the mouse coordinates on a keyboard event?

No, simply track mousemove events and continuously save the current position in case you get a keyboard event.


Cache mouse position in a global variable in every mousemove event and use it when a key event fires:

var mousePosition = {x:0, y:0};
$(document).bind('mousemove',function(mouseMoveEvent){
mousePosition.x = mouseMoveEvent.pageX;
mousePosition.y = mouseMoveEvent.pageY;
});
$(document).bind('keyup', function(keyUpEvent){
  $('body').append($('<p/>').text('x:' + mousePosition.x + ' * y: ' + mousePosition.y));
});

JSBIN: http://jsbin.com/uxecuj/4

JavaScript without jQuery:

var mousePosition = {x:0, y:0};
document.addEventListener('mousemove', function(mouseMoveEvent){
  mousePosition.x = mouseMoveEvent.pageX;
  mousePosition.y = mouseMoveEvent.pageY;
}, false);

document.addEventListener('keyup', function(keyUpEvent){
  var divLog = document.querySelector('#log'),
      log = 'x:' + mousePosition.x + ' * y: ' + mousePosition.y,
      p = document.createElement('p').innerHTM = log;
  divLog.appendChild(p);
}, false);

Here's the POJS equivalent of other answers that is cross browser back to IE 6 (and probably IE 5 but I don't have it to test any more). No global variables even:

function addEvent(el, evt, fn) {
  if (el.addEventListener) {
    el.addEventListener(evt, fn, false);
  } else if (el.attachEvent) {
    el.attachEvent('on' + evt, fn);
  }
}


(function () {
  var x, y;
  window.onload = function() {
    addEvent(document.body, 'mousemove', function(e) {
      // Support IE event model
      e = e || window.event;
      x = e.pageX || e.clientX;  
      y = e.pageY || e.clientY;
    });

    // Show coords, assume element with id "d0" exists
    addEvent(document.body, 'keypress', function() {
      document.getElementById('d0').innerHTML = x + ',' + y;
    });
  }
}());

But there are bigger issues. Key events are only dispatched if an element that can receive keyboard input is focused (input, textarea, and so on). Also, if the user scrolls the screen without moving the mouse, the coordinates will probably be wrong.

An alternative solution is to use CSS to replace the cursor with a custom animation.


If you're using jQuery, you can do the following (assuming you have an image with id="wheelImage" and whose position is set to absolute), write the following inside your keydown event. Here we use the global properties pageX and pageY that are passed to any handler. You can also use jQuery's shiftKey property to check if the shift key has been pressed.

$().keydown(function(e) {
  if (e.shiftKey) { 
     e.preventDefault();
     $('#wheelImage').css('left',e.pageX ).css('top', e.pageY);
  }  
}); 

Cache the mouse position.

var x = 0, y = 0;
document.addEventListener('mousemove', function(e){
    x = e.pageX
    y = e.pageY;
}, false);

document.addEventListener('keyup', function(e){
    console.log(x + ' ' + y);
}, false);

Or with JS Ninja Library.

var x = 0, y = 0;
$(document).mousemove(function(e){
    x = e.pageX
    y = e.pageY;
});
$(document).keypressed(function() {
    console.log(x + ' ' + y);
});