Herhangi bir fare hareketi olayı olmadan (fareyi hareket ettirmeden) sayfa yüklendikten sonra JavaScript ile fare konumunu almak mümkün müdür?
mousemove
olay ekleyerek tarayıcıyı yavaşlatmak istemezsiniz .
Herhangi bir fare hareketi olayı olmadan (fareyi hareket ettirmeden) sayfa yüklendikten sonra JavaScript ile fare konumunu almak mümkün müdür?
mousemove
olay ekleyerek tarayıcıyı yavaşlatmak istemezsiniz .
Yanıtlar:
Gerçek cevap: Hayır, bu mümkün değil.
Tamam, sadece bir yol düşündüm. Sayfanızın tamamını, belgenin tamamını kapsayan bir div ile yerleştirin. Bunun içinde , her biri 1 piksel boyutunda 2.000 x 2.000 <a>
öğe oluşturun ( :hover
sözde sınıf IE 6'da çalışacaktır, bkz.). Bir özelliği değiştiren öğeler :hover
için bir CSS kuralı oluşturun <a>
(diyelim font-family
). Yük işleyicinizde, vurgulu yazı tipini bulana kadar / bulana kadar 4 milyon <a>
öğenin her birinde dolaşın. Belgede koordinatları elde etmek için bu öğeden geri çekin.currentStyle
getComputedStyle()
DİKKAT BU YAPMAYIN .
<a>
verilen dikdörtgenleri kapsayan bir çift eleman yaparak (boyutlandırılmış <img>
elemanların mutlak konumlandırmasını kullanarak ) her seferinde dikdörtgenleri daraltarak döngü yapın . Evet, çok saçma, ama bu bilgiyi ilk fareden önce alamıyor.
Edit 2020: Bu artık çalışmaz. Öyle görünüyor ki, tarayıcı satıcıları bunu düzeltti. Çoğu tarayıcı kromu kullandığından, çekirdeğinde olabilir.
Eski cevap: Ayrıca mouseenter'ı bağlayabilirsiniz (fare imleci sayfanın içindeyken sayfa yeniden yüklendikten sonra bu olay tetiklenir). Bozuk kodun genişletilmesi hile yapmalıdır:
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;
}
Ayrıca, fare imleci etkinliğinde x ve y değerlerini null değerine ayarlayabilirsiniz. Böylece kullanıcının imleçle sayfanızda olup olmadığını kontrol edebilirsiniz.
mouseleave
setleri durumunda x
ve y
hiç arkasına null
veya'undefined'
Yapabileceğiniz şey, x
y
imleciniz ve koordinatları , fare her hareket ettiğinde bunları güncellemek ve depolanan konumla ihtiyacınız olanı yapmak için bir aralıkta bir işlevi çağırmaktır.
Bunun dezavantajı elbette farenin çalışması için en az bir başlangıç hareketinin gerekli olmasıdır. İmleç konumunu en az bir kez güncellediği sürece, tekrar hareket edip etmediğine bakılmaksızın konumunu bulabiliriz.
var cursorX;
var cursorY;
document.onmousemove = function(e){
cursorX = e.pageX;
cursorY = e.pageY;
}
setInterval(checkCursor, 1000);
function checkCursor(){
alert("Cursor at: " + cursorX + ", " + cursorY);
}
Önceki kod, imlecinizin nerede olduğunu belirten bir mesajla saniyede bir güncellenir. Umarım bu yardımcı olur.
cursorX/Y
herhangi bir olay gerçekleşmeden önce bu değişkeni doldurmanın bir yolunu arıyordum .
Tim Down'ın önerdiğine benzer bir şey deneyebilirsiniz - ancak ekrandaki her piksel için öğelere sahip olmak yerine, yalnızca 2-4 öğe (kutu) oluşturun ve ekrandaki olası yerleri bölmek için konumlarını, genişliklerini, yüksekliklerini dinamik olarak değiştirin. 2-4 özyinelemeyle, böylece farenin gerçek konumunu hızlı bir şekilde bulur.
Örneğin - ilk elemanlar ekranın sağ ve sol yarısını, daha sonra üst ve alt yarıyı alır. Şimdiye kadar, farenin hangi çeyreğinde bulunduğunu zaten biliyoruz, tekrarlayabiliyoruz - bu alanın hangi çeyreğini keşfedin ...
@Tim Down'ın cevabı, 2.000 x 2.000 <a>
öğe oluşturursanız gerçekleşmez:
Tamam, sadece bir yol düşündüm. Sayfanızın tamamını, belgenin tamamını kapsayan bir div ile yerleştirin. Bunun içinde, her biri 1 piksel boyutunda, 2.000 x 2.000 öğe oluşturun (diyelim: vurgulu sözde sınıf IE 6'da çalışacaktır, bkz.). Bir özelliği değiştiren öğeler için bir CSS: fareyle üzerine gelme kuralı oluşturun (diyelim ki font ailesi). Yük işleyicinizde, vurgulu yazı tipini bulana kadar currentStyle / getComputedStyle () öğesini kontrol ederek 4 milyon öğenin her birinde dolaşın. Belgede koordinatları elde etmek için bu öğeden geri çekin.
DİKKAT BU YAPMAYIN.
Ancak aynı anda 4 milyon öğe oluşturmak zorunda değilsiniz, bunun yerine ikili arama kullanın. Bunun <a>
yerine 4 element kullanın:
<a>
öğeyegetComputedStyle()
Fonksiyonu kullanarak hangi farenin hangi fareyle üzerine geldiğini belirleyinBu şekilde, ekranınızın 2048 pikselden daha geniş olmadığı düşünülürse, bu adımları en fazla 11 kez tekrarlamanız gerekir.
Böylece maksimum 11 x 4 = 44 <a>
eleman üreteceksiniz .
Fare konumunu tam olarak bir piksele ayarlamanız gerekmiyorsa, ancak 10 piksel hassasiyetin iyi olduğunu söyleyin. Adımları en fazla 8 kez tekrarlarsınız, bu nedenle maksimum 8 x 4 = 32 <a>
eleman çizmeniz gerekir .
Ayrıca <a>
, DOM genellikle yavaş olduğundan elemanları oluşturmak ve sonra yok etmek de işe yaramaz. Bunun yerine, sadece ilk 4 yeniden kullanabilirsiniz <a>
elemanları ve sadece ayarlamak onların top
, left
, width
veheight
adımlarda senin kadar döngü.
Şimdi, 4 oluşturmak <a>
da aşırıya kaçıyor. Bunun yerine, her bir dikdörtgeni <a>
test ederken aynı öğeyi yeniden kullanabilirsiniz getComputedStyle()
. Bu nedenle, arama alanını 2 x 2 <a>
öğeye bölmek yerine, tek bir <a>
öğeyi top
ve left
stil özellikleriyle taşıyarak yeniden kullanın .
Yani, tek ihtiyacınız olan tek bir <a>
eleman width
ve height
maksimum 11 kez değiştirmek ve onun top
ve left
maksimum 44 kez değiştirmek ve tam fare pozisyonuna sahip olacaksınız.
En basit çözüm ancak% 100 doğru değil
$(':hover').last().offset()
Sonuç: Sonuç , kullanıcı sekmeyi değiştirdiğinde en {top: 148, left: 62.5}
yakın öğe boyutuna ve geri dönüşüne bağlıdırundefined
undefined
ne olursa olsun geri döner . Bunu nasıl kullanacağınızı açıklayabilir misiniz?
undefined
İmleç herhangi bir öğenin üzerine gelmediğinde (veya tarayıcı odağı kaybettiğinde) dönecektir . Konsoldan test yapıyorsanız bir zaman aralığı ayarlamanız gerekebilir ..
setTimeout
çalıştı. Ben jsfiddle kullanıyordum ve haklısın, asla bir hover olayına çarpmadı çünkü play'i her tıkladığında DOM'u yeniden çiziyor. Bu ipucunu başkaları için eklemenizi tavsiye ederim.
Belki bir zamanlayıcılı bir üst sayfanız olduğunu ve belirli bir süre veya bir görev tamamlandıktan sonra kullanıcıyı yeni bir sayfaya yönlendirdiğinizi düşünüyorum. Şimdi imlecin konumunu istiyorsunuz ve bekledikleri için fareye dokunmaları gerekmiyor. Standart olayları kullanarak üst sayfadaki fareyi izleyin ve son değeri bir get veya post değişkeninde yeni sayfaya iletin.
JHarding'in kodunu ana sayfanızda kullanabilirsiniz, böylece en son konum her zaman global bir değişkende kullanılabilir:
var cursorX;
var cursorY;
document.onmousemove = function(e){
cursorX = e.pageX;
cursorY = e.pageY;
}
Bu, bu sayfaya ana sayfanız dışındaki yollarla giden kullanıcılara yardımcı olmaz.
Tim Down'ın fikri gibi yatay / dikey bir arama gerçekleştirdim (önce yatay olarak düzenlenmiş dikey çizgi bağlantılarıyla dolu bir div yapın, sonra dikey olarak düzenlenmiş yatay çizgi bağlantılarıyla dolu bir div yapın ve basitçe hangisinin üzerine gelindiğini görün) ve oldukça hızlı çalışıyor. Ne yazık ki, KDE üzerinde Chrome 32 üzerinde çalışmıyor.
jsfiddle.net/5XzeE/4/
İmlecin yerini almak için fareyi hareket ettirmeniz gerekmez . Konum, fareyle üzerine gelme dışındaki olaylarda da bildirilir . İşte bu tıklama olay bir örnek olarak:
document.body.addEventListener('click',function(e)
{
console.log("cursor-location: " + e.clientX + ',' + e.clientY);
});
@ SuperNova'nın cevabına dayanarak , ES6 sınıflarını kullanarak this
geri aramalarınızda bağlamı doğru tutan bir yaklaşım :
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));
İşte benim çözümüm. Her yerde kullanabileceğiniz window.currentMouseX ve window.currentMouseY özelliklerini dışa aktarır . Vurgulu bir öğenin (varsa) konumunu başlangıçta kullanır ve daha sonra doğru değerleri ayarlamak için fare hareketlerini dinler.
(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 Kaynağı: 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;
}
Ben div ve piksel sayma dışında makul bir çözüm olabilir düşünüyorum .. lol
Sadece animasyon karesini veya bir fonksiyonun zaman aralığını kullanın. sadece başlatmak için yine de bir kez bir fare etkinliğine ihtiyacınız olacak, ancak teknik olarak bunu istediğiniz yere konumlandırıyorsunuz.
Aslında fare hareketi olmadan her zaman kukla bir div izliyoruz.
// create a div(#mydiv) 1px by 1px set opacity to 0 & position:absolute;
Aşağıda mantık ..
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);
}