Как получить положение мыши без событий (без перемещения мыши)? - PullRequest
245 голосов
/ 08 апреля 2010

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

Ответы [ 13 ]

304 голосов
/ 08 апреля 2010

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

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

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

109 голосов
/ 10 апреля 2014

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

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;
}

Вы также можете установить x и y в null для mouseleave-события. Таким образом, вы можете проверить, находится ли пользователь на вашей странице с его курсором.

79 голосов
/ 24 января 2012

Что вы можете сделать, это создать переменные для 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);
}

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

9 голосов
/ 11 февраля 2015

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

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

4 голосов
/ 10 апреля 2017

@ Ответ Тима Дауна бесполезен, если вы отображаете 2000 x 2000 <a> элементов:

Хорошо, я только что придумал способ. Наложите свою страницу на div, который охватывает весь документ. Внутри этого создайте (скажем) 2000 х 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 раз, учитывая, что ваш экран не шире, чем 2048 пикселей.

Таким образом, вы получите максимум 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 max 11 раз, и измените его top и left max 44 раза, и вы получите точное положение мыши.

2 голосов
/ 10 января 2018

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

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

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

2 голосов
/ 17 октября 2013

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

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

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

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

1 голос
/ 03 сентября 2018

Вот мое решение. Он экспортирует свойства 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's 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;
    });
}())

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

1 голос
/ 28 июня 2017

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

document.body.addEventListener('click',function(e)
{
    console.log("cursor-location: " + e.clientX + ',' + e.clientY);
});
1 голос
/ 06 ноября 2013

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

jsfiddle.net / 5XzeE / 4 /

...