Ist es möglich, die Mausposition mit JavaScript nach dem Laden der Seite ohne Mausbewegungsereignis (ohne Bewegung der Maus) zu ermitteln?
mousemove
Ereignisse verlangsamen .
Ist es möglich, die Mausposition mit JavaScript nach dem Laden der Seite ohne Mausbewegungsereignis (ohne Bewegung der Maus) zu ermitteln?
mousemove
Ereignisse verlangsamen .
Antworten:
Richtige Antwort: Nein, das ist nicht möglich.
OK, ich habe gerade über einen Weg nachgedacht. Überlagern Sie Ihre Seite mit einem Div, der das gesamte Dokument abdeckt. Erstellen Sie darin beispielsweise 2.000 x 2.000 <a>
Elemente (damit die :hover
Pseudoklasse in IE 6 funktioniert, siehe), die jeweils 1 Pixel groß sind. Erstellen Sie eine CSS- :hover
Regel für die <a>
Elemente, die eine Eigenschaft ändern (z. B. font-family
). Durchlaufen Sie in Ihrem Load-Handler jedes der 4 Millionen <a>
Elemente und überprüfen Sie currentStyle
/, getComputedStyle()
bis Sie das Element mit der Hover-Schriftart finden. Extrapolieren Sie von diesem Element zurück, um die Koordinaten innerhalb des Dokuments zu erhalten.
NB TUN SIE DAS NICHT .
<a>
, das bestimmte Rechtecke abdeckt ( <img>
vermutlich unter absoluter Positionierung von Größenelementen), wobei die Rechtecke jedes Mal verkleinert werden. Ja, es ist lächerlich, aber es ist nicht möglich, diese Informationen vor dem ersten Mauszug zu erhalten.
Edit 2020: Das funktioniert nicht mehr. Es scheint so, dass die Browser-Anbieter dies behoben haben. Da die meisten Browser auf Chrom setzen, befindet es sich möglicherweise in seinem Kern.
Alte Antwort: Sie können auch mouseenter einbinden (dieses Ereignis wird nach dem erneuten Laden der Seite ausgelöst, wenn sich der Mauszeiger innerhalb der Seite befindet). Das Erweitern des Codes von Corrupted sollte den Trick machen:
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;
}
Sie können x und y auch bei einem Mausblattereignis auf null setzen. So können Sie mit dem Cursor überprüfen, ob sich der Benutzer auf Ihrer Seite befindet.
mouseleave
Fall , dass Sätze x
und y
zurück zu null
oder'undefined'
Sie können Variablen für die x
und die y
Koordinaten Ihres Cursors erstellen , diese aktualisieren, wenn sich die Maus bewegt, und eine Funktion in einem Intervall aufrufen, um mit der gespeicherten Position das zu tun, was Sie benötigen.
Der Nachteil dabei ist natürlich, dass mindestens eine erste Bewegung der Maus erforderlich ist, damit sie funktioniert. Solange der Cursor seine Position mindestens einmal aktualisiert, können wir seine Position finden, unabhängig davon, ob er sich wieder bewegt.
var cursorX;
var cursorY;
document.onmousemove = function(e){
cursorX = e.pageX;
cursorY = e.pageY;
}
setInterval(checkCursor, 1000);
function checkCursor(){
alert("Cursor at: " + cursorX + ", " + cursorY);
}
Der vorhergehende Code wird einmal pro Sekunde mit einer Meldung aktualisiert, wo sich Ihr Cursor befindet. Ich hoffe das hilft.
cursorX/Y
Variablen zu füllen , bevor ein Ereignis eintritt.
Sie könnten etwas Ähnliches ausprobieren, wie Tim Down vorgeschlagen hat - aber anstatt Elemente für jedes Pixel auf dem Bildschirm zu haben, erstellen Sie nur 2-4 Elemente (Kästchen) und ändern Sie deren Position, Breite und Höhe dynamisch, um die noch möglichen Positionen auf dem Bildschirm zu teilen um 2-4 rekursiv, wodurch die reale Position der Maus schnell gefunden wird.
Zum Beispiel - erste Elemente nehmen die rechte und linke Hälfte des Bildschirms ein, danach die obere und untere Hälfte. Inzwischen wissen wir bereits, in welchem Viertel des Bildschirms sich die Maus befindet, können wiederholen - entdecken Sie, welches Viertel dieses Raumes ...
Die Antwort von @Tim Down ist nicht performant, wenn Sie 2.000 x 2.000 <a>
Elemente rendern :
OK, ich habe gerade über einen Weg nachgedacht. Überlagern Sie Ihre Seite mit einem Div, der das gesamte Dokument abdeckt. Erstellen Sie darin beispielsweise 2.000 x 2.000 Elemente (damit die: hover-Pseudoklasse in IE 6 funktioniert, siehe) mit jeweils 1 Pixel Größe. Erstellen Sie eine CSS: Hover-Regel für die Elemente, die eine Eigenschaft ändern (z. B. Schriftfamilie). Durchlaufen Sie in Ihrem Load-Handler jedes der 4 Millionen Elemente und überprüfen Sie currentStyle / getComputedStyle (), bis Sie das mit der Hover-Schriftart finden. Extrapolieren Sie von diesem Element zurück, um die Koordinaten innerhalb des Dokuments zu erhalten.
NB TUN SIE DAS NICHT.
Sie müssen jedoch nicht 4 Millionen Elemente gleichzeitig rendern, sondern die binäre Suche verwenden. Verwenden Sie <a>
stattdessen einfach 4 Elemente:
<a>
ElementegetComputedStyle()
Bestimmen Sie mithilfe der Funktion, in welchem Rechteck sich die Maus befindetAuf diese Weise müssten Sie diese Schritte maximal elf Mal wiederholen, da Ihr Bildschirm nicht breiter als 2048 Pixel ist.
Sie generieren also maximal 11 x 4 = 44 <a>
Elemente.
Wenn Sie die Mausposition nicht genau auf ein Pixel genau bestimmen müssen, aber sagen, dass eine Genauigkeit von 10 Pixel in Ordnung ist. Sie würden die Schritte höchstens 8 Mal wiederholen, sodass Sie maximal 8 x 4 = 32 <a>
Elemente zeichnen müssten .
Auch das Erzeugen und anschließende Zerstören der <a>
Elemente wird nicht ausgeführt, da DOM im Allgemeinen langsam ist. Stattdessen können Sie nur die ersten 4 wiederzuverwenden <a>
Elemente und nur ihre anpassen top
, left
, width
und height
wie Sie Schleife durch die Schritte.
Jetzt ist das Erstellen von 4 ebenfalls <a>
ein Overkill. Stattdessen können Sie dasselbe <a>
Element beim Testen getComputedStyle()
in jedem Rechteck wiederverwenden . Anstatt den Suchbereich in 2 x 2 <a>
Elemente aufzuteilen, verwenden Sie einfach ein einzelnes <a>
Element, indem Sie es mit den Stil- top
und left
Stileigenschaften verschieben.
Alles, was Sie brauchen, ist ein einzelnes <a>
Element, das seine width
und height
max 11-mal und seine top
und left
max 44-mal ändert, und Sie haben die genaue Mausposition.
Die einfachste Lösung, aber nicht 100% genau
$(':hover').last().offset()
Ergebnis: {top: 148, left: 62.5}
Das Ergebnis hängt von der nächstgelegenen Elementgröße ab und wird zurückgegeben, undefined
wenn der Benutzer die Registerkarte wechselt
undefined
trotzdem zurück. Können Sie erläutern, wie dies zu verwenden ist?
undefined
wenn der Cursor kein Element bewegt (oder wenn der Browser den Fokus verloren hat). Möglicherweise müssen Sie ein Zeitintervall festlegen, wenn Sie von der Konsole aus testen.
setTimeout
hat funktioniert. Ich habe jsfiddle verwendet und Sie haben Recht, es hat nie ein Schwebeflugereignis getroffen, da es das DOM jedes Mal neu zeichnet, wenn Sie auf Wiedergabe klicken. Ich würde empfehlen, diesen Hinweis für andere hinzuzufügen.
Ich stelle mir vor, dass Sie möglicherweise eine übergeordnete Seite mit einem Timer haben und den Benutzer nach einer bestimmten Zeit oder nach Abschluss einer Aufgabe auf eine neue Seite weiterleiten. Jetzt möchten Sie die Cursorposition und weil sie warten, berühren sie nicht unbedingt die Maus. Verfolgen Sie also die Maus auf der übergeordneten Seite mithilfe von Standardereignissen und übergeben Sie den letzten Wert in einer get- oder post-Variablen an die neue Seite.
Sie können den JHarding-Code auf Ihrer übergeordneten Seite verwenden, sodass die neueste Position immer in einer globalen Variablen verfügbar ist:
var cursorX;
var cursorY;
document.onmousemove = function(e){
cursorX = e.pageX;
cursorY = e.pageY;
}
Dies hilft Benutzern nicht, die mit anderen Mitteln als Ihrer übergeordneten Seite zu dieser Seite navigieren.
Ich habe eine horizontale / vertikale Suche implementiert (erst ein Div voller vertikal angeordneter vertikaler Linienverknüpfungen, dann ein Div voll vertikal angeordneter horizontaler Linienverknüpfungen und einfach sehen, welche den Schwebezustand hat), wie Tim Downs Idee oben, und es funktioniert ziemlich schnell. Funktioniert leider nicht auf Chrome 32 unter KDE.
jsfiddle.net/5XzeE/4/
Sie müssen die Maus nicht bewegen , um die Position des Cursors zu ermitteln. Der Standort wird auch über andere Ereignisse als Mausbewegungen gemeldet . Hier ist ein Klickereignis als Beispiel:
document.body.addEventListener('click',function(e)
{
console.log("cursor-location: " + e.clientX + ',' + e.clientY);
});
In Anlehnung an die Antwort von @ SuperNova finden Sie hier einen Ansatz, bei dem ES6-Klassen verwendet werden, um den Kontext this
in Ihrem Rückruf korrekt zu halten:
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));
Hier ist meine Lösung. Es exportiert die Eigenschaften window.currentMouseX und window.currentMouseY, die Sie überall verwenden können. Es verwendet zunächst die Position eines schwebenden Elements (falls vorhanden) und hört anschließend Mausbewegungen ab, um die richtigen Werte festzulegen.
(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- Quelle: 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;
}
Ich denke, ich habe vielleicht eine vernünftige Lösung, ohne Divs und Pixel zu zählen
Verwenden Sie einfach einen Animationsrahmen oder ein Zeitintervall einer Funktion. Sie benötigen zwar einmal ein Mausereignis, um es zu initiieren, aber technisch positionieren Sie dieses, wo immer Sie möchten.
Im Wesentlichen verfolgen wir jederzeit ein Dummy-Div ohne Mausbewegung.
// create a div(#mydiv) 1px by 1px set opacity to 0 & position:absolute;
Unten ist die Logik ..
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);
}