Jak uzyskać pozycję myszy bez zdarzeń (bez poruszania myszką)?

Czy możliwe jest uzyskanie pozycji myszy przy pomocy JavaScript po załadowaniu strony bez żadnego zdarzenia ruchu myszki (bez poruszania myszką)?

Author: Norbert Tamas, 2010-04-08

12 answers

Prawdziwa odpowiedź: nie, to niemożliwe.

OK, właśnie wymyśliłem sposób. Nakładaj na swoją stronę div, który obejmuje cały dokument. Wewnątrz tego, utwórz (powiedzmy) 2000 x 2000 <a> elementów (tak, że pseudo-klasa :hover będzie działać w IE 6, Zobacz), każdy 1 piksel wielkości. Utwórz regułę CSS :hover dla tych elementów <a>, które zmieniają właściwość (powiedzmy font-family). W programie obsługi obciążenia przejrzyj każdy z 4 milionów elementów <a>, sprawdzając currentStyle / getComputedStyle() dopóki nie znajdziesz jedynego z czcionką hover. Ekstrapoluj z tego elementu, aby uzyskać współrzędne w dokumencie.

N. B. nie rób tego .

 284
Author: Tim Down,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-08 15:29:50

Można również zaczepić mouseenter (zdarzenie to jest wywoływane po przeładowaniu strony, gdy kursor myszy znajduje się wewnątrz strony). Rozszerzenie uszkodzonego kodu powinno załatwić sprawę:

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

Można również ustawić x i y na null w mouseleave-event. Możesz więc sprawdzić, czy użytkownik jest na twojej stronie za pomocą kursora.

 94
Author: SuperNova,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-16 09:31:56

Możesz utworzyć zmienne dla współrzędnych x i y kursora, zaktualizować je za każdym razem, gdy mysz się porusza i wywołać funkcję w interwale, aby zrobić to, czego potrzebujesz z zapisaną pozycją.

Minusem tego jest oczywiście to, że przynajmniej jeden początkowy ruch myszy jest wymagany, aby to działało. Dopóki kursor aktualizuje swoją pozycję co najmniej raz, jesteśmy w stanie znaleźć jego pozycję niezależnie od tego, czy porusza się ponownie.

var cursorX;
var cursorY;
document.onmousemove = function(e){
    cursorX = e.pageX;
    cursorY = e.pageY;
}
setInterval(checkCursor, 1000);
function checkCursor(){
    alert("Cursor at: " + cursorX + ", " + cursorY);
}

Poprzedni kod aktualizuje się raz na sekundę z informacją, gdzie znajduje się kursor. Mam nadzieję, że to pomoże.

 76
Author: JHarding,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-29 06:58:44

Możesz spróbować czegoś podobnego do tego, co sugerował Tim Down - ale zamiast mieć elementy dla każdego piksela na ekranie, Utwórz tylko 2-4 elementy (pola) i zmieniaj ich lokalizację, szerokość, wysokość dynamicznie, aby podzielić możliwe jeszcze lokalizacje na ekranie przez 2-4 rekurencyjnie, dzięki czemu szybko odnajdziesz rzeczywistą lokalizację myszy.

Na przykład-pierwsze elementy zajmują prawą i lewą połowę ekranu, następnie górną i dolną połowę. Do tej pory już wiemy, w której ćwiartce ekranu mysz znajduje się, są w stanie powtórzyć-odkryć, który kwartał tej przestrzeni...

 9
Author: AlexTR,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-12 06:23:37

Wyobrażam sobie, że być może masz Stronę nadrzędną z timerem i po pewnym czasie lub wykonaniu zadania, przekazujesz użytkownika do nowej strony. Teraz chcesz pozycję kursora, a ponieważ czekają, nie muszą dotykać myszy. Śledź mysz na stronie nadrzędnej za pomocą standardowych zdarzeń i przekaż ostatnią wartość do nowej strony w zmiennej get lub post.

Możesz użyć kodu JHarding na swojej stronie nadrzędnej, aby ostatnia pozycja była zawsze dostępne w zmiennej globalnej:

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

To nie pomoże użytkownikom, którzy nawigują do tej strony w inny sposób niż Strona nadrzędna.

 2
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-17 19:59:38

@odpowiedź Tim Down nie jest wykonalna, jeśli wyrenderujesz 2000 x 2000 <a> elementy:

OK, właśnie wymyśliłem sposób. Nakładać na swoją stronę div, który obejmuje cały dokument. W środku stwórz (powiedzmy) 2000 x 2000 elementów (tak aby pseudo-Klasa :hover działała w IE 6, Zobacz), każdy 1 piksel wielkości. Tworzenie reguły CSS: hover dla tych elementów to zmienia właściwość (powiedzmy font-family). W programie obsługi ładunku, cykl przez każdy z 4 milionów elementy, sprawdzanie currentStyle / getComputedStyle () dopóki nie znajdziesz tego z najedź czcionką. Ekstrapolować z powrotem z tego elementu, aby uzyskać współrzędne w dokumencie. Nie rób tego.

Ale nie musisz renderować 4 milionów elementów na raz, zamiast tego użyj wyszukiwania binarnego. Wystarczy użyć 4 <a> elementów zamiast:

  • Krok 1: rozważ cały ekran jako początkowy obszar wyszukiwania
  • Krok 2: podziel obszar wyszukiwania na 2 x 2 = 4 prostokąt <a> elementy
  • Krok 3: za pomocą funkcji getComputedStyle() Określ, w którym kierunku kursuje mysz prostokątna
  • Krok 4: zmniejsz obszar wyszukiwania do tego prostokąta i powtórz od kroku 2.

W ten sposób musisz powtórzyć te kroki maksymalnie 11 razy, biorąc pod uwagę, że Twój ekran nie jest szerszy niż 2048px.

Więc wygenerujesz max 11 x 4 = 44 <a> elementów.

Jeśli nie musisz określać pozycji myszy dokładnie do piksela, ale powiedzmy, że precyzja 10px jest OK. Czynności te powtarza się maksymalnie 8 razy, więc trzeba narysować maksymalnie 8 x 4 = 32 <a> elementów.

Również generowanie i niszczenie elementów <a> nie jest wykonywane, ponieważ DOM jest zwykle powolny. Zamiast tego możesz po prostu ponownie użyć początkowych 4 <a> elementów i dostosować ich top, left, width i height Jak pętli przez kroki.

Teraz tworzenie 4 <a> również jest przesadą. Zamiast tego możesz ponownie użyć tego samego elementu <a> podczas testowania dla getComputedStyle() w każdy prostokąt. Tak więc, zamiast dzielić obszar wyszukiwania na 2 x 2 <a> elementów, po prostu użyj ponownie pojedynczego elementu <a>, przenosząc go za pomocą właściwości stylu top i left.

Więc wystarczy jeden element <a> zmienić swoje width i height maksymalnie 11 razy, a zmienić swoje top i left maksymalnie 44 razy, a będziesz miał dokładną pozycję myszy.

 2
Author: Alex Peterson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-10 14:58:31

Zaimplementowałem wyszukiwanie poziome / pionowe (najpierw zrób div pełen pionowych linków liniowych ułożonych poziomo, a następnie zrób div pełen poziomych linków liniowych ułożonych pionowo, i po prostu zobacz, który z nich ma stan hover), jak pomysł Tim Down powyżej, i to działa dość szybko. Niestety, nie działa na Chrome 32 w KDE.

Jsfiddle.net/5XzeE/4/

 1
Author: user2958613,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-06 01:42:37
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
Author: Corrupted,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-09 14:31:57

Nie musisz poruszać myszką, aby uzyskać położenie kursora. Lokalizacja jest również podawana w przypadku zdarzeń innych niż mousemove . Oto click-event jako przykład:

document.body.addEventListener('click',function(e)
{
    console.log("cursor-location: " + e.clientX + ',' + e.clientY);
});
 0
Author: Lonnie Best,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-28 17:29:58

Najprostsze rozwiązanie, ale nie w 100% dokładne

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

Wynik: {top: 148, left: 62.5}
wynik zależy od najbliższego rozmiaru elementu i zwraca undefined gdy użytkownik przełącza zakładkę

 0
Author: StefansArya,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-10 12:19:16

Riffing on @ SuperNova 's answer , here' s a approach using ES6 classes that keeps the context for this correct in your callback:

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));
 0
Author: Patrick Berkeley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-02 06:16:00

Ponieważ nikt nie oferował pół-użytecznego rozwiązania, oto moje. Eksportuje okno.okno currentMouseX i .currentMouseY właściwości można używać wszędzie. Początkowo używa pozycji elementu zawieszonego (jeśli istnieje), a następnie nasłuchuje ruchów myszy, aby ustawić prawidłowe wartości.

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

Composr CMS Źródło: https://github.com/ocproducts/composr/commit/a851c19f925be20bc16bfe016be42924989f262e#diff-b162dc9c35a97618a96748639ff41251R1202

 0
Author: Salman Abbas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-02 21:27:40