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


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

12 231

12 ответов:

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

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

Б. Н.НЕ ДЕЛАЙ ЭТОГО.

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

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-event. Таким образом, вы можете проверить, если пользователь находится на Вашей странице с его курсором.

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

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

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

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

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

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

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

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

ответ@Tim Down не выполняется, если вы визуализируете 2,000 x 2,000 <a> элементы:

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

таким образом, вы будете генерировать max 11 x 4 = 44 <a> элементы.

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

также генерируя и затем уничтожая <a> элементы не performat как 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 раз, и вы будете иметь точное положение мыши.

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

jsfiddle.net/5XzeE/4/

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

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

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

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

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

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

играли @сверхновой, вот подход с использованием классов 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's `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));

Так как никто не предложил наполовину полезное решение, вот мое. Он экспортирует