Как получить позицию мыши без событий (без перемещения мыши)?

Можно ли получить позицию мыши с JavaScript после загрузки страницы без какого-либо события перемещения мыши (без перемещения мыши)?

Ответ 1

Реальный ответ: Нет, это невозможно.

Хорошо, я только что подумал об этом. Наложите свою страницу на div, который охватывает весь документ. Внутри этого, создайте (скажем) 2 000 x 2000 <a> элементов (так что псевдокласс класса :hover будет работать в IE 6, см.), Каждый размером 1 пиксель. Создайте правило CSS :hover для тех элементов <a>, которые изменяют свойство (скажем, font-family). В вашем обработчике нагрузки пройдите через каждый из 4 миллионов элементов <a>, проверив currentStyle/getComputedStyle(), пока не найдете тот, у кого есть шрифт зависания. Экстраполируйте назад этот элемент, чтобы получить координаты внутри документа.

N.B. НЕ ДЕЛАЙТЕ ЭТО.

Ответ 2

Вы также можете подключить mouseenter (это событие запускается после перезагрузки страницы, когда мышка находится внутри страницы). Расширение поврежденного кода должно делать трюк:

var x = null;
var y = null;
    
document.addEventListener('mousemove', onMouseUpdate, false);
document.addEventListener('mouseenter', onMouseUpdate, false);
    
function onMouseUpdate(e) {
  x = e.pageX;
  y = e.pageY;
  console.log(x, y);
}

function getMouseX() {
  return x;
}

function getMouseY() {
  return y;
}

Ответ 3

Что вы можете сделать, так это создавать переменные для координат x и y вашего курсора, обновлять их всякий раз, когда мышь перемещается и вызывать функцию с интервалом, чтобы делать то, что вам нужно, с сохраненной позицией.

Недостатком этого, конечно же, является то, что для его работы требуется хотя бы одно начальное движение мыши. Пока курсор обновляет свое положение хотя бы один раз, мы можем найти его положение независимо от того, будет ли он двигаться снова.

var cursorX;
var cursorY;
document.onmousemove = function(e){
    cursorX = e.pageX;
    cursorY = e.pageY;
}
setInterval(checkCursor, 1000);
function checkCursor(){
    alert("Cursor at: " + cursorX + ", " + cursorY);
}

Предыдущий код обновляется один раз в секунду с сообщением о том, где находится ваш курсор. Надеюсь, это поможет.

Ответ 4

Вы можете попробовать что-то похожее на то, что предложил Тим Даун, но вместо того, чтобы иметь элементы для каждого пикселя на экране, создайте всего 2-4 элемента (ячейки) и измените их местоположение, ширину и высоту динамически, чтобы разделить все возможное места на экране на 2-4 рекурсивно, тем самым быстро обнаруживая реальное местоположение мыши.

Например - первые элементы принимают правую и левую половину экрана, а затем верхнюю и нижнюю половину. К настоящему времени мы уже знаем, в какой четверти экрана находится мышь, можно повторить - найдите, в какой части этого пространства...

Ответ 5

@Tim Down ответ не работает, если вы отображаете 2 000 x 2000 <a> элементов:

Хорошо, я только что подумал об этом. Наложите свою страницу на div, чтобы охватывает весь документ. Внутри этого, создайте (скажем) 2000 x 2000 элементов (так что псевдокласс класса hover будет работать в IE 6, см.), каждый 1 пиксель в размере. Создайте правило CSS: hover для этих элементов который изменяет свойство (пусть, шрифт-семья). В вашем обработчике нагрузки, цикл через каждый из 4 миллионов элементов, проверка currentStyle/getComputedStyle(), пока не найдете тот, который наведите шрифт. Экстраполируйте назад этот элемент, чтобы получить координаты в документе.

N.B. НЕ ДЕЛАЙТЕ ЭТО.

Но вам не нужно отображать 4 миллиона элементов одновременно, вместо этого используйте двоичный поиск. Вместо этого используйте 4 <a>:

  • Шаг 1: рассмотрим весь экран в качестве начальной области поиска
  • Шаг 2: Разделите область поиска на 2 элемента x 2 = 4 прямоугольника <a>.
  • Шаг 3: Используя функцию getComputedStyle(), определите, в какой прямоугольной мышке наводится
  • Шаг 4: Уменьшите область поиска до этого прямоугольника и повторите с шага 2.

Таким образом, вам нужно будет повторить эти шаги максимум 11 раз, учитывая, что ваш экран не шире 2048px.

Итак, вы создадите максимум 11 x 4 = 44 <a> элементов.

Если вам не нужно определять положение мыши точно в пиксель, но скажите, что точность 10px в порядке. Вы повторите шаги не более 8 раз, поэтому вам нужно будет нарисовать максимум 8 x 4 = 32 <a> элементов.

Кроме того, генерация и уничтожение элементов <a> не выполняется, поскольку DOM обычно медленный. Вместо этого вы можете просто повторно использовать начальные 4 <a> элементы и просто отрегулировать их top, left, width и height по мере прохождения шагов.

Теперь создание 4 <a> также является излишним. Вместо этого вы можете использовать один и тот же элемент <a> для тестирования для getComputedStyle() в каждом прямоугольнике. Таким образом, вместо разделения области поиска на 2 x 2 <a> элементы просто повторно используют один элемент <a>, перемещая его с помощью свойств стиля top и left.

Итак, вам нужно только один элемент <a> изменить его width и height максимум 11 раз и изменить его top и left максимум 44 раза, и у вас будет точная позиция мыши.

Ответ 6

Самое простое решение, но не 100% точное

$(':hover').last().offset()

Результат: {top: 148, left: 62.5}
Результат зависит от ближайшего размера элемента и возвращает undefined, когда пользователь переключил вкладку

Ответ 7

Я предполагаю, что, возможно, у вас есть родительская страница с таймером, и через определенное время или задача завершена, вы пересылаете пользователя на новую страницу. Теперь вам нужна позиция курсора, и поскольку они ждут, они не обязательно касаются мыши. Поэтому следите за мышью на родительской странице с помощью стандартных событий и передавайте последнее значение на новую страницу в переменной get или post.

Вы можете использовать код JHarding на родительской странице, чтобы последняя позиция всегда была доступна в глобальной переменной:

var cursorX;
var cursorY;
document.onmousemove = function(e){
    cursorX = e.pageX;
    cursorY = e.pageY;
}

Это не поможет пользователям, которые переходят на эту страницу, кроме вашей родительской страницы.

Ответ 8

Я выполнил горизонтальный/вертикальный поиск (сначала сделайте div, полный вертикальных линий, расположенных горизонтально, затем сделайте div, полный горизонтальных линий, расположенных вертикально, и просто посмотрите, какой из них имеет состояние зависания), как идея Тима Дауна выше, и он работает довольно быстро. К сожалению, не работает на Chrome 32 в KDE.

jsfiddle.net/5XzeE/4/

Ответ 9

Вам не нужно переместить мышь, чтобы получить местоположение курсора. Местоположение также сообщается о событиях, отличных от mousemove. Здесь click-event в качестве примера:

document.body.addEventListener('click',function(e)
{
    console.log("cursor-location: " + e.clientX + ',' + e.clientY);
});

Ответ 10

Здесь мое решение. Он экспортирует свойства window.currentMouseX и window.currentMouseY, которые вы можете использовать где угодно. Сначала он использует положение элемента наведения (если он есть), а затем слушает движения мыши, чтобы установить правильные значения.

(function () {
    window.currentMouseX = 0;
    window.currentMouseY = 0;

    // Guess the initial mouse position approximately if possible:
    var hoveredElement = document.querySelectorAll(':hover');
    hoveredElement = hoveredElement[hoveredElement.length - 1]; // Get the most specific hovered element

    if (hoveredElement != null) {
        var rect = hoveredElement.getBoundingClientRect();
        // Set the values from hovered element position
        window.currentMouseX = window.scrollX + rect.x;
        window.currentMouseY = window.scrollY + rect.y;
    }

    // Listen for mouse movements to set the correct values
    document.addEventListener('mousemove', function (e) {
        window.currentMouseX = e.pageX;
        window.currentMouseY = e.pageY;
    });
}())

CMS Composr Источник: https://github.com/ocproducts/composr/commit/a851c19f925be20bc16bfe016be42924989f262e#diff-b162dc9c35a97618a96748639ff41251R1202

Ответ 11

var x = 0;
var y = 0;

document.addEventListener('mousemove', onMouseMove, false)

function onMouseMove(e){
    x = e.clientX;
    y = e.clientY;
}

function getMouseX() {
    return x;
}

function getMouseY() {
    return y;
}

Ответ 12

Riffing on @SuperNova answer, здесь используется подход, использующий классы ES6, которые сохраняют контекст для this правильным в вашем обратном вызове:

class Mouse {
  constructor() {
    this.x = 0;
    this.y = 0;
    this.callbacks = {
      mouseenter: [],
      mousemove: [],
    };
  }

  get xPos() {
    return this.x;
  }

  get yPos() {
    return this.y;
  }

  get position() {
    return `${this.x},${this.y}`;
  }

  addListener(type, callback) {
    document.addEventListener(type, this); // Pass `this` as the second arg to keep the context correct
    this.callbacks[type].push(callback);
  }

  // `handleEvent` is part of the browser `EventListener` API.
  // https://developer.mozilla.org/en-US/docs/Web/API/EventListener/handleEvent
  handleEvent(event) {
    const isMousemove = event.type === 'mousemove';
    const isMouseenter = event.type === 'mouseenter';

    if (isMousemove || isMouseenter) {
      this.x = event.pageX;
      this.y = event.pageY;
    }

    this.callbacks[event.type].forEach((callback) => {
      callback();
    });
  }
}

const mouse = new Mouse();

mouse.addListener('mouseenter', () => console.log('mouseenter', mouse.position));
mouse.addListener('mousemove', () => console.log('mousemove A', mouse.position));
mouse.addListener('mousemove', () => console.log('mousemove B', mouse.position));

Ответ 13

Я думаю, что у меня может быть разумное решение без подсчета div и пикселей.. lol

Просто используйте кадр анимации или временной интервал функции. вам все равно понадобится событие мыши один раз, хотя только для того, чтобы инициировать, но технически вы размещаете его там, где вам когда-либо нужно.

По сути, мы всегда отслеживаем фиктивный div без движения мыши.

// create a div(#mydiv) 1px by 1px set opacity to 0 & position:absolute;

Ниже приводится логика..

var x,y;


$('body').mousemove(function( e ) {

    var x = e.clientX - (window.innerWidth / 2);
    var y = e.clientY - (window.innerHeight / 2);
 }


function looping (){

   /* track my div position 60 x 60 seconds!
      with out the mouse after initiation you can still track the dummy div.x & y
      mouse doesn't need to move.*/

   $('#mydiv').x = x;    // css transform x and y to follow 
   $('#mydiv)'.y = y;

   console.log(#mydiv.x etc)

   requestAnimationFrame( looping , frame speed here);
}