Как получить положение мыши без событий (без перемещения мыши)?
Можно ли получить положение мыши с помощью JavaScript после загрузки страницы без какого-либо события перемещения мыши (без перемещения мыши)?
15 ответов
Реальный ответ: нет, это невозможно.
Хорошо, я только что придумал способ. Наложите свою страницу с div, который покрывает весь документ. Внутри этого создайте (скажем) 2000 x 2000 <a>
элементы (так что :hover
псевдокласс будет работать в IE 6, см.), каждый размером 1 пиксель. Создать CSS :hover
правило для тех <a>
элементы, которые изменяют свойство (скажем, font-family
). В вашем обработчике нагрузки, переберите каждый из 4 миллионов <a>
элементы, проверка currentStyle
/ getComputedStyle()
пока вы не найдете тот с шрифтом наведения. Экстраполировать обратно из этого элемента, чтобы получить координаты в документе.
NB не делай этого.
Вы также можете перехватить указатель мыши (это событие вызывается после перезагрузки страницы, когда курсор мыши находится внутри страницы). Расширение кода 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-события. Таким образом, вы можете проверить, находится ли пользователь на вашей странице с помощью курсора.
Что вы можете сделать, это создать переменные для 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);
}
Предыдущий код обновляется раз в секунду с сообщением о том, где находится ваш курсор. Надеюсь, это поможет.
Ответ @Tim Down бесполезен, если вы рендерите 2000 x 2000 <a>
элементы:
Хорошо, я только что придумал способ. Наложите свою страницу с div, который покрывает весь документ. Внутри этого создайте (скажем) 2000 x 2000 элементов (чтобы псевдокласс:hover работал в IE 6, см.), Каждый размером 1 пиксель. Создайте правило CSS:hover для тех элементов, которые изменяют свойство (скажем, font-family). В вашем обработчике нагрузки циклически просматривайте каждый из 4 миллионов элементов, проверяя currentStyle / getComputedStyle(), пока не найдете тот, который имеет шрифт hover. Экстраполировать обратно из этого элемента, чтобы получить координаты в документе.
NB не делай этого.
Но вам не нужно отображать 4 миллиона элементов одновременно, вместо этого используйте бинарный поиск. Просто используйте 4 <a>
элементы вместо:
- Шаг 1: Рассмотрим весь экран как начальную область поиска
- Шаг 2: Разделите область поиска на 2 x 2 = 4 прямоугольника
<a>
элементы - Шаг 3: Использование
getComputedStyle()
функция определения, в каком прямоугольнике мышь парит - Шаг 4: Уменьшите область поиска до этого прямоугольника и повторите с шага 2.
Таким образом, вам нужно будет повторить эти шаги максимум 11 раз, учитывая, что ваш экран не шире, чем 2048 пикселей.
Таким образом, вы получите максимум 11 х 4 = 44 <a>
элементы.
Если вам не нужно точно определять положение мыши с точностью до пикселя, но скажите, что с точностью 10px все в порядке. Вы должны повторить шаги не более 8 раз, поэтому вам нужно нарисовать максимум 8 x 4 = 32 <a>
элементы.
Также генерирует и затем уничтожает <a>
элементы не выполняются, так как DOM обычно работает медленно. Вместо этого вы можете просто использовать начальные 4 <a>
элементы и просто настроить их top
, left
, width
а также height
как вы проходите через шаги.
Теперь создаем 4 <a>
это тоже излишество. Вместо этого вы можете использовать один и тот же <a>
элемент для тестирования getComputedStyle()
в каждом прямоугольнике. Таким образом, вместо разделения области поиска на 2 х 2 <a>
элементы просто повторно использовать один <a>
элемент, перемещая его с top
а также left
свойства стиля.
Итак, все, что вам нужно, это один <a>
элемент изменить его width
а также height
макс 11 раз, и измените его top
а также left
макс 44 раза, и вы будете иметь точное положение мыши.
Вы можете попробовать нечто похожее на то, что предложил Тим Даун, но вместо того, чтобы иметь элементы для каждого пикселя на экране, создайте всего 2-4 элемента (поля) и динамически изменяйте их местоположение, ширину и высоту, чтобы разделить все еще возможные места на экране. на 2-4 рекурсивно, таким образом, быстро находя реальное местоположение мыши.
Например - первые элементы занимают правую и левую половину экрана, а затем верхнюю и нижнюю. К настоящему времени мы уже знаем, в какой четверти экрана находится мышь, можем повторить - выяснить, какая четверть этого пространства...
Так как никто не предложил решение, которое можно использовать наполовину, вот мое. Он экспортирует свойства 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;
});
}())
CMS Composr Источник: https://github.com/ocproducts/composr/commit/a851c19f925be20bc16bfe016be42924989f262e
Самое простое решение, но не на 100% точное
$(':hover').last().offset()
Результат: {top: 148, left: 62.5}
Результат зависит от ближайшего размера элемента и возврата undefined
когда пользователь переключил вкладку
Да, это возможно.
Если вы добавите к документу событие «mouseover», оно сработает мгновенно, и вы сможете получить положение мыши, конечно, если указатель мыши находился над документом.
document.addEventListener('mouseover', setInitialMousePos, false);
function setInitialMousePos( event ) {
console.log( event.clientX, event.clientY);
document.removeEventListener('mouseover', setInitialMousePos, false);
}
Раньше можно было считывать положение мыши через
window.event
но сейчас он устарел.
Не положение мыши, но, если вы ищете текущее положение курсора (для таких случаев, как получение последнего набранного символа и т. Д.), То нижеприведенный фрагмент работает нормально.
Это даст вам указатель курсора, связанный с текстовым содержимым.
window.getSelection().getRangeAt(0).startOffset
Я предполагаю, что, возможно, у вас есть родительская страница с таймером, и по истечении определенного времени или задачи вы перенаправляете пользователя на новую страницу. Теперь вам нужно положение курсора, и поскольку они ждут, они не обязательно касаются мыши. Поэтому следите за мышью на родительской странице, используя стандартные события, и передайте последнее значение новой странице в переменной get или post.
Вы можете использовать код JHarding на своей родительской странице, чтобы последняя позиция всегда была доступна в глобальной переменной:
var cursorX;
var cursorY;
document.onmousemove = function(e){
cursorX = e.pageX;
cursorY = e.pageY;
}
Это не поможет пользователям, которые переходят на эту страницу другими способами, кроме вашей родительской страницы.
Я реализовал поиск по горизонтали / вертикали (сначала сделайте 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;
}
Опираясь на ответ @SuperNova, вот подход с использованием классов 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));
Вам не нужно перемещать мышь, чтобы получить местоположение курсора. Местоположение также сообщается о событиях, кроме указателя мыши. Вот, например, событие клика:
document.body.addEventListener('click',function(e)
{
console.log("cursor-location: " + e.clientX + ',' + e.clientY);
});
Я думаю, что у меня может быть разумное решение без подсчета 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);
}