Получить позицию мыши в Javascript без использования события onmousemove [duplicate]

IMHO нет эквивалента remove_if(). Вы не можете изменить порядок карты. Таким образом, remove_if() не может поставить интересующие вас пары в конце, на которые вы можете позвонить erase().

224
задан Norbert Tamas 8 April 2010 в 16:17
поделиться

11 ответов

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

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

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

275
ответ дан Tim Down 15 August 2018 в 17:54
поделиться
  • 1
    ха-ха - в какой-то момент вы должны google вокруг и посмотреть, сможете ли вы выяснить, сколько людей действительно реализовало это – Pointy 8 April 2010 в 16:46
  • 2
    Приобретенный, просто для чистого веселья. – Ryan McGrath 8 April 2010 в 17:03
  • 3
    Фактически, он реализуется без большой загрузки процессора (я думаю, я его не тестировал). На dom готово построить & lt; a & gt; элементы с javascript, возьмите положение мыши и затем удалите все & lt; a & gt; элементы. На мышеловке у вас должна быть другая функция, чтобы взять положение мыши. Во всяком случае, это было весело. – machineaddict 16 August 2012 в 06:40
  • 4
    Возможно, это может быть практическим с бинарным поиском? Loop, создающий пару элементов & lt; a & gt; , покрывающих заданные прямоугольники (с использованием абсолютного позиционирования элементов размера & lt; img & gt; , я полагаю), каждый раз сокращая прямоугольники. Да, это смешно, но так не удается получить эту информацию до первой mousemove. – Darius Bacon 28 May 2013 в 23:24
  • 5
    stackoverflow.com/a/8543879/27024 говорит, что наведение не срабатывает либо до тех пор, пока мышь не будет двигаться в первый раз. Это сфокусирует эту схему. – Darius Bacon 28 May 2013 в 23:28

Ответ @Tim Down не работает, если вы выставляете 2 000 x 2000 & lt; a & gt; элементов:

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

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

Но вам не нужно отображать 4 миллиона элементов одновременно, вместо этого используйте бинарный поиск. Просто используйте 4 & lt; a & gt; элементы:

  • Шаг 1: Рассмотрите весь экран как начальную область поиска
  • Шаг 2: Разделить область поиска в 2 x 2 = 4 прямоугольника & lt; a & gt; элементы
  • Шаг 3: Используя функцию getComputedStyle () , определите, в какой прямоугольной мышке hovers
  • Шаг 4: Уменьшите область поиска до этого прямоугольника и повторите с шага 2.

Таким образом, вам нужно будет повторить эти шаги максимум 11 раз, учитывая ваши экран не шире 2048px.

Итак, вы создадите максимум 11 x 4 = 44 & lt; a & gt; элементов.

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

Также генерировать и затем уничтожать & lt; a & gt; не выполняется, поскольку DOM обычно медленный. Вместо этого вы можете просто повторно использовать исходные 4 & lt; a & gt; элементы и просто отрегулировать их верх , влево , width и height , когда вы выполняете шаги.

Теперь создание 4 & lt; a & gt; также является излишним. Вместо этого вы можете использовать один и тот же элемент & lt; a & gt; для тестирования для getComputedStyle () в каждом прямоугольнике. Таким образом, вместо разделения области поиска на 2 x 2 & lt; a & gt; элементы просто повторно используют один элемент & lt; a , перемещая его с помощью top и left .

Итак, все, что вам нужно, это один элемент & lt; a & gt; изменить его ширину и height не более 11 раз, а верхняя верхняя и оставлена ​​ max 44 раза, и вы будете иметь точную позицию мыши.

3
ответ дан Alex Peterson 15 August 2018 в 17:54
поделиться
  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;  }  
0
ответ дан Corrupted 15 August 2018 в 17:54
поделиться
  • 1
    Разве это не требует от пользователя перемещения мыши? – Paul Hiemstra 9 November 2012 в 16:53

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

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

  var cursorX;  var cursorY;  document.onmousemove = function (e) {cursorX = e.pageX;  cursorY = e.pageY;  } setInterval (checkCursor, 1000);  function checkCursor () {alert ("Курсор в:" + cursorX + "," + cursorY);  }  

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

75
ответ дан Jackson 15 August 2018 в 17:54
поделиться
  • 1
    Вы читали тему этого сообщения? OP спрашивает, как получить координаты мыши без использования события. Однако ваш пост предполагает использование события onmousemove. – jake 18 December 2012 в 02:36
  • 2
    @jake Несмотря на то, что OP специально запросил метод, не связанный с событиями, этот ответ приносит пользу другим, которые пришли сюда, чтобы найти ответ и, возможно, обходной путь. Кроме того, я бы рассмотрел этот ответ частично в теме, поскольку, насколько я знаю, это лучший способ получить позицию курсора в любой момент времени, не используя непосредственно события. Тем не менее, ответ мог бы быть сформулирован более подробно с указанием факта и предлагать способ избежать комментариев в комментариях. – jpeltoniemi 1 April 2013 в 01:50
  • 3
    @Pichan Мне это не помогло, потому что я искал способ заполнить эту переменную cursorX / Y до того, как произойдет какое-либо событие. – polkovnikov.ph 9 February 2016 в 18:11
  • 4
    очень немногие пользователи не будут запускать события мыши – SuperUberDuper 30 August 2016 в 01:33
  • 5
    Осторожно, это может быть дорогостоящим, чтобы держать слушателя mousemove. Я бы предложил воссоздать слушателя в промежутке и уничтожить слушателя после получения координат. – KRB 1 March 2017 в 19:50

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

  document.body.addEventListener ('click', function (e) {console.log ("cursor-location:" + e.clientX + '  , '+ e.clientY);});   
0
ответ дан Lonnie Best 15 August 2018 в 17:54
поделиться

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

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

8
ответ дан marc_s 15 August 2018 в 17:54
поделиться

Riffing on @ ответ SuperNova , вот подход с использованием классов ES6, который поддерживает контекст для , этот правильный в вашем обратном вызове:

класс Мышь {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); // Передаем `this`, как второй arg, чтобы сохранить контекст правильно this.callbacks [type] .push (callback); } // `handleEvent` является частью API-интерфейса браузера EventListener. // 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) = & gt; {callback ();}); }} const mouse = new Mouse (); mouse.addListener ('mouseenter', () = & gt; console.log ('mouseenter', mouse.position)); mouse.addListener ('mousemove', () = & gt; console.log ('mousemove A', mouse.position)); mouse.addListener ('mousemove', () = & gt; console.log ('mousemove B', mouse.position));

0
ответ дан Patrick Berkeley 15 August 2018 в 17:54
поделиться

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

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

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

0
ответ дан StefansArya 15 August 2018 в 17:54
поделиться
  • 1
    Для меня он возвращает undefined независимо. Можете ли вы рассказать о том, как использовать это? – tresf 8 March 2018 в 17:06
  • 2
    Он возвратил undefined , когда курсор не зависал ни один элемент (или когда браузер потерял фокус). Возможно, вам потребуется установить временной интервал, если вы тестируете его с консоли. – StefansArya 10 March 2018 в 05:12
  • 3
    Благодарю. setTimeout работал. Я использовал jsfiddle, и вы правы, он никогда не попадал в событие hover, потому что он перерисовывает DOM каждый раз, когда вы нажимаете play. Я бы рекомендовал добавить этот намек другим. – tresf 10 March 2018 в 09:03

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

89
ответ дан SuperNova 15 August 2018 в 17:54
поделиться
  • 1
    Казалось бы, это единственный полезный ответ, который кажется странным. Действительно (в последних версиях Firefox, Chrome и IE11), mouseenter запускается при загрузке страницы и предоставляет правильные координаты. Изменено ли поведение браузера в этой области за последние несколько лет? – Peter Hansen 23 November 2014 в 03:10
  • 2
    Фактически "мышиный центр" похоже, не добавляет никакой ценности. Я тестировал со следующим jsfiddle в Chrome и IE, и они не показывают кордиты, пока вы не поместите мышь во внутренний документ (панель результатов): jsfiddle.net/xkpd784o/1 – Mariano Desanze 14 May 2015 в 00:54
  • 3
    @Proton: переместите указатель мыши на панель результатов в область конечной панели. ПЕРВАЯ страница полностью загружена и не перемещается. После onload страница сразу же знает положение мыши. Движение мыши не требуется. Таким образом, mouseenter также запускается, когда страница загружается, а мышь находится внутри области документа. То есть, чего первоначально хотел ОП. Никто другой не дает такого ответа. – SuperNova 15 May 2015 в 06:31
  • 4
    Потенциально полезным дополнением является добавление функции для события mouseleave , которое устанавливает x и y обратно в null или 'не определено' – rtpax 14 December 2016 в 00:02
  • 5
    @ brillout.com Я только что протестировал его в Chrome 57 под окнами: работает как шарм. Что не сработало в вашем тесте? – SuperNova 24 April 2017 в 08:38

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

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

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

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

2
ответ дан user 15 August 2018 в 17:54
поделиться

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

jsfiddle.net/5XzeE/4 /

1
ответ дан user2958613 15 August 2018 в 17:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: