Можно ли получить позицию мыши с помощью JavaScript после загрузки страницы без какого-либо события движения мыши (без движения мыши)?
Как получить положение мыши без событий (без перемещения мыши)?
Ответы (14)
Реальный ответ: нет, это невозможно.
Хорошо, я только что придумал способ. Наложите на свою страницу div, охватывающий весь документ. Внутри него создайте (скажем) 2000 x 2000 <a>
элементов (чтобы псевдокласс :hover
работал в IE 6, см.), Каждый размером 1 пиксель. Создайте :hover
правило CSS для тех <a>
элементов, которые изменяют свойство (скажем, font-family
). В обработчике загрузки циклически переберите каждый из 4 миллионов элементов <a>
, проверяя currentStyle
/ getComputedStyle()
, пока не найдете тот, у которого наведен шрифт. Экстраполируйте этот элемент обратно, чтобы получить координаты в документе.
N.B. НЕ ДЕЛАЙТЕ ЭТОГО.
<a>
элементов, покрывающих заданные прямоугольники (я полагаю, используя абсолютное позиционирование <img>
элементов), каждый раз сжимая прямоугольники. Да, это смешно, но невозможно получить эту информацию до первого движения мыши.
- person Darius Bacon; 29.05.2013
Изменить 2020: Это не больше работает. Похоже, что производители браузеров исправили это. Поскольку большинство браузеров полагаются на хром, он может быть в его ядре.
Старый ответ: вы также можете подключить mouseenter (это событие запускается после перезагрузки страницы, когда курсор мыши находится внутри страницы). Расширение кода 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. Таким образом, вы можете проверить, находится ли пользователь на вашей странице с курсором.
mouseleave
, которая устанавливает для x
и y
обратно значение null
или 'undefined'
.
- person rtpax; 14.12.2016
mouseenter
, ни mousemove
не срабатывают при загрузке страницы, даже если курсор находится внутри страницы. См. Мой ответ для лучшего решения: stackoverflow.com/a/52141050/362006
- person Salman von Abbas; 03.09.2018
Что вы можете сделать, так это создать переменные для координат x
и y
вашего курсора, обновлять их при каждом движении мыши и вызывать функцию в интервале, чтобы делать то, что вам нужно, с сохраненной позицией.
Обратной стороной этого, конечно же, является то, что для работы требуется хотя бы одно начальное движение мыши. Пока курсор обновляет свое положение хотя бы один раз, мы можем найти его положение независимо от того, двигается ли он снова.
var cursor_x = -1;
var cursor_y = -1;
document.onmousemove = function(event)
{
cursor_x = event.pageX;
cursor_y = event.pageY;
}
setInterval(check_cursor, 1000);
function check_cursor(){console.log('Cursor at: '+cursor_x+', '+cursor_y);}
Предыдущий код обновляется раз в секунду с сообщением о том, где находится ваш курсор. Надеюсь, это поможет.
cursorX/Y
до того, как произойдет какое-либо событие.
- person polkovnikov.ph; 09.02.2016
Ответ @Tim Down неэффективен, если вы визуализируете 2,000 x 2,000 <a>
элементов:
Хорошо, я только что придумал способ. Наложите свою страницу на div, который покрывает весь документ. Внутри него создайте (скажем) 2 000 x 2 000 элементов (чтобы псевдокласс: hover работал в IE 6, см.), Каждый размером 1 пиксель. Создайте правило CSS: hover для тех элементов, которые изменяют свойство (скажем, font-family). В обработчике загрузки циклически переберите каждый из 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>
элементов.
Если вам не нужно определять положение мыши с точностью до пикселя, но допустим, что точность 10 пикселей - это нормально. Вы должны повторить эти шаги не более 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 раза, и вы получите точное положение мыши.
Вы можете попробовать что-то похожее на то, что предложил Тим Даун, но вместо того, чтобы иметь элементы для каждого пикселя на экране, создайте всего 2-4 элемента (блока) и динамически измените их расположение, ширину и высоту, чтобы разделить все же возможные местоположения на экране. на 2-4 рекурсивно, таким образом быстро находя реальное местоположение мыши.
Например - первые элементы занимают правую и левую половину экрана, затем верхнюю и нижнюю половину. К настоящему времени мы уже знаем, в какой четверти экрана находится мышь, умеем повторять - узнаем, в какой четверти этого пространства ...
Самое простое решение, но не на 100% точное
$(':hover').last().offset()
Результат: {top: 148, left: 62.5}
Результат зависит от размера ближайшего элемента и возвращает undefined
, когда пользователь переключил вкладку
undefined
. Не могли бы вы рассказать, как это использовать?
- person tresf; 08.03.2018
undefined
, когда курсор не наведен на какой-либо элемент (или когда браузер потерял фокус). Вам может потребоваться установить временной интервал, если вы тестируете с консоли.
- person StefansArya; 10.03.2018
setTimeout
работал. Я использовал jsfiddle, и вы правы, он никогда не запускал событие зависания, потому что он перерисовывает DOM каждый раз, когда вы нажимаете кнопку воспроизведения. Я бы порекомендовал добавить эту подсказку другим.
- person tresf; 10.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
window.addEventListener('mousemove', function (e) {
window.currentMouseX = e.pageX;
window.currentMouseY = e.pageY;
}, /*useCapture=*/true);
}())
Composr CMS Источник: https://github.com/ocproducts/composr/фиксация/a851c19f925be20bc16bfe016be42924989f262e#дифф-b162dc9c35a97618a96748639ff41251R1202
Я реализовал поиск по горизонтали / вертикали (сначала сделайте div, полный ссылок с вертикальными линиями, расположенными по горизонтали, затем сделайте div, полный ссылок с горизонтальными линиями, расположенных вертикально, и просто посмотрите, какая из них находится в состоянии наведения), как идея Тима Дауна выше, и работает довольно быстро. К сожалению, не работает в Chrome 32 на KDE.
jsfiddle.net/5XzeE/4/
Вам не нужно перемещать мышь, чтобы определить местоположение курсора. Местоположение также сообщается для других событий, кроме mousemove. Вот пример события клика:
document.body.addEventListener('click',function(e)
{
console.log("cursor-location: " + e.clientX + ',' + e.clientY);
});
Опираясь на ответ @ 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));
Я предполагаю, что, возможно, у вас есть родительская страница с таймером, и по прошествии определенного времени или выполнения задачи вы перенаправляете пользователя на новую страницу. Теперь вам нужна позиция курсора, и поскольку они ждут, они не обязательно касаются мыши. Поэтому отслеживайте мышь на родительской странице, используя стандартные события, и передайте последнее значение на новую страницу в переменной get или post.
Вы можете использовать код JHarding на своей родительской странице, чтобы последняя позиция всегда была доступна в глобальной переменной:
var cursorX;
var cursorY;
document.onmousemove = function(e){
cursorX = e.pageX;
cursorY = e.pageY;
}
Это не поможет пользователям, которые переходят на эту страницу другими способами, кроме вашей родительской.
Не положение мыши, но, если вы ищете текущее положение курсора (для таких случаев, как получение последнего набранного символа и т. Д.), То нижеприведенный фрагмент работает нормально.
Это даст вам курсор. индекс, относящийся к текстовому контенту.
window.getSelection().getRangeAt(0).startOffset
Я думаю, что у меня может быть разумное решение без подсчета 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);
}
mousemove
событий. - person Tomáš Zato - Reinstate Monica   schedule 29.11.2014:hover
, но он не работает без фактического перемещения мыши: jsfiddle.net / z9w20f53 - person trusktr   schedule 18.02.2020