Czy możliwe jest uzyskanie pozycji myszy za pomocą JavaScript po wczytaniu strony bez żadnego zdarzenia ruchu myszy (bez poruszania myszą)?
mousemove
zdarzeń.
Czy możliwe jest uzyskanie pozycji myszy za pomocą JavaScript po wczytaniu strony bez żadnego zdarzenia ruchu myszy (bez poruszania myszą)?
mousemove
zdarzeń.
Odpowiedzi:
Prawdziwa odpowiedź: nie, nie jest to możliwe.
OK, właśnie wymyśliłem sposób. Nałóż stronę na div, który obejmuje cały dokument. Wewnątrz tego utwórz (powiedzmy) 2000 x 2000 <a>
elementów (aby :hover
pseudoklasa działała w IE 6, zobacz), każdy o rozmiarze 1 piksela. Utwórz :hover
regułę CSS dla tych <a>
elementów, które zmieniają właściwość (powiedzmy font-family
). W module obsługi ładunku przewijaj kolejno każdy z 4 milionów <a>
elementów, sprawdzając currentStyle
/, getComputedStyle()
aż znajdziesz ten z czcionką aktywowaną. Ekstrapoluj z powrotem z tego elementu, aby uzyskać współrzędne w dokumencie.
NB NIE Rób tego .
<a>
elementów pokrywających dane prostokąty (jak <img>
sądzę, stosując bezwzględne pozycjonowanie zwymiarowanych elementów), zmniejszając za każdym razem prostokąty. Tak, to śmieszne, ale nie jest w stanie uzyskać tych informacji przed pierwszym ruchem myszy.
Edycja 2020: To już nie działa. Wydaje się, że producenci przeglądarek załatali to. Ponieważ większość przeglądarek korzysta z chromu, może być w jego rdzeniu.
Stara odpowiedź: możesz także zaczepić mouseenter (to zdarzenie jest uruchamiane po przeładowaniu strony, gdy kursor myszy znajduje się na stronie). Rozszerzenie kodu Corrupt 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żesz także ustawić x i y na wartość null dla zdarzenia mouseleave-event. Możesz więc sprawdzić, czy użytkownik jest na Twojej stronie za pomocą kursora.
mouseleave
przypadku, który wyznacza x
i y
tylnej do null
lub'undefined'
Możesz tworzyć zmienne dla x
i y
współrzędne kursora, aktualizować je za każdym razem, gdy mysz się porusza, i wywoływać funkcję w określonym przedziale czasu, aby zrobić to, czego potrzebujesz z zapisaną pozycją.
Wadą tego jest oczywiście to, że wymagany jest co najmniej jeden początkowy ruch myszy. Tak długo, jak 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ę co sekundę komunikatem o tym, gdzie znajduje się kursor. Mam nadzieję, że to pomoże.
cursorX/Y
zmiennych przed jakimkolwiek zdarzeniem.
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 dynamicznie zmieniaj ich położenie, szerokość i wysokość, aby podzielić możliwe lokalizacje na ekranie rekursywnie przez 2-4, dzięki czemu szybko znajdujemy 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 wiemy już, w której części ekranu znajduje się mysz, jesteśmy w stanie powtarzać - odkryć, która ćwiartka tego miejsca ...
Odpowiedź @Tim Down nie jest skuteczna, jeśli renderujesz 2000 x 2000 <a>
elementów:
OK, właśnie wymyśliłem sposób. Nałóż stronę na div, który obejmuje cały dokument. Wewnątrz tego utwórz (powiedzmy) 2000 x 2000 elementów (aby pseudo-klasa: hover działała w IE 6, zobacz), każdy o rozmiarze 1 piksela. Utwórz regułę CSS: najedź dla tych elementów, które zmieniają właściwość (powiedzmy rodzinę czcionek). W module obsługi ładunku przewijaj kolejno każdy z 4 milionów elementów, sprawdzając currentStyle / getComputedStyle (), aż znajdziesz ten z czcionką aktywowaną. Ekstrapoluj z powrotem z tego elementu, aby uzyskać współrzędne w dokumencie.
NB NIE Rób tego.
Ale nie musisz renderować 4 milionów elementów jednocześnie, zamiast tego użyj wyszukiwania binarnego. <a>
Zamiast tego użyj 4 elementów:
<a>
elementy prostokątne getComputedStyle()
funkcji określ, w której myszy ma się poruszać prostokątW ten sposób musisz powtórzyć te kroki maksymalnie 11 razy, biorąc pod uwagę, że ekran nie jest szerszy niż 2048 pikseli.
Wygenerujesz więc maksymalnie 11 x 4 = 44 <a>
elementy.
Jeśli nie musisz określać położenia myszy dokładnie do piksela, ale powiedz, że precyzja 10px jest OK. Powtórzyłbyś kroki co najwyżej 8 razy, więc musisz narysować maksymalnie 8 x 4 = 32 <a>
elementy.
Również generowanie, a następnie niszczenie <a>
elementów nie jest wykonywane, ponieważ DOM jest na ogół powolny. Zamiast tego, można po prostu ponowne początkowe 4 <a>
elementów i po prostu dostosować swoje top
, left
, width
a height
jak ty pętlę przez kroki.
Teraz tworzenie 4 <a>
to także przesada. Zamiast tego możesz użyć tego samego <a>
elementu do testowania getComputedStyle()
w każdym prostokącie. Zamiast dzielić obszar wyszukiwania na 2 x 2 <a>
elementy, wystarczy ponownie użyć jednego <a>
elementu, przenosząc go za pomocą właściwości top
i left
stylu.
Wszystko czego potrzebujesz to jeden <a>
element, zmień jego width
i height
maks. 11 razy, zmień jego top
i left
maks. 44 razy, a będziesz miał dokładnie pozycję myszy.
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 zmieni kartę
undefined
niezależnie. Czy potrafisz wyjaśnić, jak z tego korzystać?
undefined
gdy kursor nie będzie unosił się nad jakimkolwiek elementem (lub gdy przeglądarka straci fokus). Może być konieczne ustawienie interwału czasowego, jeśli
setTimeout
pracował Używałem jsfiddle i masz rację, nigdy nie uderzył w zdarzenie najechania myszą, ponieważ przerysowuje DOM za każdym razem, gdy grasz. Polecam dodanie tej wskazówki innym.
Wyobrażam sobie, że może masz stronę nadrzędną z zegarem i po pewnym czasie lub wykonaniu zadania przekierowujesz użytkownika na nową stronę. Teraz chcesz pozycję kursora, a ponieważ czekają, niekoniecznie dotykają myszy. Śledź więc 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 najnowsza pozycja była zawsze dostępna 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 przechodzą na tę stronę w sposób inny niż strona nadrzędna.
Zaimplementowałem wyszukiwanie poziome / pionowe (najpierw wykonuję div pełen pionowe łącza liniowe ułożone poziomo, a następnie robię div pełen poziome łącza liniowe ułożone pionowo i po prostu sprawdzam, który z nich jest w stanie najechania), podobnie jak pomysł Tima Down powyżej, i działa dość szybko. Niestety nie działa w Chrome 32 na KDE.
jsfiddle.net/5XzeE/4/
Nie musisz poruszać myszą, aby uzyskać lokalizację kursora. Lokalizacja jest również zgłaszana w przypadku zdarzeń innych niż ruch myszy . Oto przykład zdarzenia kliknięcia :
document.body.addEventListener('click',function(e)
{
console.log("cursor-location: " + e.clientX + ',' + e.clientY);
});
Wracając do odpowiedzi @ SuperNova , oto podejście wykorzystujące klasy ES6, które zachowuje kontekst dla this
poprawnego oddzwaniania:
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));
Oto moje rozwiązanie. Eksportuje właściwości window.currentMouseX i window.currentMouseY , których można używać w dowolnym miejscu. Wykorzystuje pozycję elementu ukrytego (jeśli istnieje) początkowo, 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
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;
}
Myślę, że mogę mieć rozsądne rozwiązanie bez liczenia div i pikseli..lol
Po prostu użyj ramki animacji lub przedziału czasowego funkcji. Nadal będziesz potrzebować zdarzenia myszy, aby zainicjować, ale technicznie ustawiasz to tam, gdzie chcesz.
Zasadniczo śledzimy atrapę div przez cały czas bez ruchu myszy.
// create a div(#mydiv) 1px by 1px set opacity to 0 & position:absolute;
Poniżej znajduje się logika ..
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);
}