Можно ли получить положение мыши с помощью JavaScript после загрузки страницы без какого-либо события перемещения мыши (без перемещения мыши)?
mousemove
событий.
Можно ли получить положение мыши с помощью JavaScript после загрузки страницы без какого-либо события перемещения мыши (без перемещения мыши)?
mousemove
событий.
Ответы:
Реальный ответ: нет, это невозможно.
Хорошо, я только что придумал способ. Наложите свою страницу с div, который покрывает весь документ. Внутри этого создайте (скажем) 2000 x 2000 <a>
элементов (чтобы :hover
псевдокласс работал в IE 6, см.), Каждый размером 1 пиксель. Создайте :hover
правило CSS для тех <a>
элементов, которые изменяют свойство (скажем font-family
). В вашем обработчике нагрузки циклически просматривайте каждый из 4 миллионов <a>
элементов, проверяя currentStyle
/, getComputedStyle()
пока не найдете тот, который имеет шрифт hover. Экстраполировать обратно из этого элемента, чтобы получить координаты в документе.
NB не делай этого .
<a>
элементов, покрывающих заданные прямоугольники ( <img>
я полагаю, используя абсолютное позиционирование размерных элементов), каждый раз сжимая прямоугольники. Да, это смешно, но невозможно получить эту информацию до первого движения мышью.
Редактировать 2020: это больше не работает. Похоже, что производители браузеров исправили это. Поскольку большинство браузеров полагаются на хром, это может быть в его ядре.
Старый ответ: Вы также можете перехватить указатель мыши (это событие вызывается после перезагрузки страницы, когда курсор мыши находится внутри страницы). Расширение кода 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'
Что вы можете сделать, это создать переменные 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);
}
Предыдущий код обновляется раз в секунду сообщением о том, где находится ваш курсор. Надеюсь, это поможет.
cursorX/Y
переменные до того, как произойдет какое-либо событие.
Вы можете попробовать нечто похожее на то, что предложил Тим Даун, но вместо того, чтобы иметь элементы для каждого пикселя на экране, создайте всего 2-4 элемента (поля) и динамически изменяйте их местоположение, ширину и высоту, чтобы разделить все еще возможные места на экране. на 2-4 рекурсивно, таким образом, быстро находя реальное местоположение мыши.
Например - первые элементы занимают правую и левую половину экрана, затем верхнюю и нижнюю. К настоящему времени мы уже знаем, в какой четверти экрана находится мышь, можем повторить - выяснить, какая четверть этого пространства ...
Ответ @Tim Down бесполезен, если вы отображаете 2000 x 2000 <a>
элементов:
Хорошо, я только что придумал способ. Наложите свою страницу с div, который покрывает весь документ. Внутри этого создайте (скажем) 2000 x 2000 элементов (чтобы псевдокласс: hover работал в IE 6, см.), Каждый размером 1 пиксель. Создайте правило CSS: hover для тех элементов, которые изменяют свойство (скажем, font-family). В вашем обработчике нагрузки циклически просматривайте каждый из 4 миллионов элементов, проверяя currentStyle / getComputedStyle (), пока не найдете тот, который имеет шрифт hover. Экстраполировать обратно из этого элемента, чтобы получить координаты в документе.
NB не делай этого.
Но вам не нужно отображать 4 миллиона элементов одновременно, вместо этого используйте бинарный поиск. Просто используйте <a>
вместо этого 4 элемента:
<a>
элементаgetComputedStyle()
функцию, определите, в каком прямоугольнике зависает мышьТаким образом, вам нужно будет повторить эти шаги максимум 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 х 2 <a>
элементов просто повторно использовать один <a>
элемент, перемещая его top
и left
свойства стиля.
Таким образом, все, что вам нужно, это один <a>
элемент, изменить его width
и height
макс. 11 раз, а также изменить его top
и left
макс. 44 раза, и вы получите точное положение мыши.
Самое простое решение, но не на 100% точное
$(':hover').last().offset()
Результат: {top: 148, left: 62.5}
результат зависит от размера ближайшего элемента и возвращается, undefined
когда пользователь переключил вкладку
undefined
независимо. Можете ли вы уточнить, как это использовать?
undefined
когда курсор не будет зависать ни от какого элемента (или когда браузер потерял фокус). Возможно, вам придется установить временной интервал, если вы проводите тестирование с консоли.
setTimeout
работал. Я использовал jsfiddle, и вы правы, он никогда не срабатывал при наведении курсора, потому что он перерисовывает DOM каждый раз, когда вы нажимаете play. Я бы порекомендовал добавить этот совет другим.
Я предполагаю, что, возможно, у вас есть родительская страница с таймером, и по истечении определенного времени или задачи вы перенаправляете пользователя на новую страницу. Теперь вам нужно положение курсора, и поскольку они ждут, они не обязательно касаются мыши. Поэтому отслеживайте мышь на родительской странице, используя стандартные события, и передайте последнее значение новой странице в переменной 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/
Вам не нужно перемещать мышь, чтобы получить местоположение курсора. Местоположение также сообщается о событиях, кроме указателя мыши . Вот пример клика в качестве примера:
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));
Вот мое решение. Он экспортирует свойства 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#diff-b162dc9c35a97618a96748639ff41251R1202
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;
}
Я думаю, что у меня может быть разумное решение без подсчета 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);
}