在没有任何鼠标移动事件(不移动鼠标)的情况下加载页面后,是否可以使用JavaScript获取鼠标位置?
答案 0 :(得分:303)
真实答案:不,这是不可能的。
好的,我刚想到了一个方法。使用覆盖整个文档的div覆盖页面。在其中,创建(比方说)2,000 x 2,000<a>
元素(以便{1}}伪类在IE 6中工作,参见),每个像素大小为1个像素。为那些更改属性的:hover
元素创建一个CSS :hover
规则(假设为<a>
)。在您的加载处理程序中,循环浏览400万个font-family
元素中的每一个,检查<a>
/ currentStyle
,直到找到具有悬停字体的元素。从该元素推断回来以获得文档中的坐标。
N.B。 不要这样做。
答案 1 :(得分:109)
您还可以挂钩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;
}
您还可以在mouseleave-event上将x和y设置为null。因此,您可以使用光标检查用户是否在您的页面上。
答案 2 :(得分:79)
您可以做的是为光标的x
和y
坐标创建变量,每当鼠标移动时更新它们,并在一定间隔内调用函数,以便根据存储位置执行所需操作
当然,这样做的缺点是至少需要一次鼠标初始移动才能使其正常工作。只要光标至少更新其位置一次,我们就能找到它的位置,无论它是否再次移动。
var cursorX;
var cursorY;
document.onmousemove = function(e){
cursorX = e.pageX;
cursorY = e.pageY;
}
setInterval(checkCursor, 1000);
function checkCursor(){
alert("Cursor at: " + cursorX + ", " + cursorY);
}
前面的代码每秒更新一次,并显示光标所在的消息。我希望这会有所帮助。
答案 3 :(得分:9)
你可以尝试类似于Tim Down建议的东西 - 但不是为屏幕上的每个像素添加元素,而是创建2-4个元素(盒子),并动态地改变它们的位置,宽度,高度以划分可能性屏幕上的位置递归2-4,从而快速找到鼠标的真实位置。
例如 - 第一个元素占据屏幕的右半部分和左半部分,然后是上半部分和下半部分。到目前为止,我们已经知道鼠标位于屏幕的四分之一处,能够重复 - 发现这个空间的四分之一......
答案 4 :(得分:4)
如果你渲染2,000 x 2,000 <a>
个元素,@ Timim的答案就不会有效:
好的,我刚想到了一个方法。使用div覆盖您的页面 涵盖整个文件。在里面,创建(比方说)2,000 x 2,000 元素(这样:hover伪类将在IE 6中工作,参见), 每个像素大小。为这些元素创建一个CSS:hover规则 这改变了一个属性(比如说font-family)。在你的负载处理程序中 循环查看400万个元素中的每个元素,进行检查 currentStyle / getComputedStyle()直到找到带有的 悬停字体。从这个元素推断回来得到坐标 在文件中。N.B。不要这样做。
但是你不必一次渲染400万个元素,而是使用二进制搜索。只需使用4个<a>
元素:
<a>
元素getComputedStyle()
函数确定鼠标悬停在哪个矩形这样,您需要重复这些步骤最多11次,因为您的屏幕不会超过2048像素。
因此,您将生成最多11 x 4 = 44 <a>
个元素。
如果你不需要确定一个像素的鼠标位置,但说10px精度是可以的。您最多重复8次步骤,因此您需要绘制最多8 x 4 = 32 <a>
个元素。
同样生成然后销毁<a>
元素并不适用,因为DOM通常很慢。相反,您可以重复使用最初的4个<a>
元素,并在循环执行步骤时调整他们的top
,left
,width
和height
。
现在,创建4 <a>
也是一种过度杀伤力。相反,您可以在每个矩形中测试<a>
时重复使用相同的getComputedStyle()
元素。因此,不是将搜索区域拆分为2 x 2 <a>
元素,而是通过使用<a>
和top
样式属性移动它来重用单个left
元素。
因此,您只需要一个<a>
元素将其width
和height
最多更改11次,并更改其top
和left
最多44时间,你将有确切的鼠标位置。
答案 5 :(得分:2)
我设想您可能有一个带有计时器的父页面,并且在一定时间或任务完成后,您将用户转发到新页面。现在你想要光标位置,因为它们正在等待,它们不一定会触摸鼠标。因此,使用标准事件在父页面上跟踪鼠标,并将最后一个值传递给get或post变量中的新页面。
您可以在父页面上使用JHarding代码,以便最终位置始终在全局变量中可用:
var cursorX;
var cursorY;
document.onmousemove = function(e){
cursorX = e.pageX;
cursorY = e.pageY;
}
这不会帮助用户通过父页以外的方式导航到此页面。
答案 6 :(得分:2)
最简单的解决方案,但不是100%准确
if( is_home() || is_front_page() ) {
get_template_part( 'template-parts/album-grid', 'index' );
}
结果:$(':hover').last().offset()
结果取决于最近的元素大小,并在用户切换选项卡时返回{top: 148, left: 62.5}
答案 7 :(得分:1)
我实现了一个水平/垂直搜索,(首先制作一个div水平排列的垂直线链接,然后制作一个垂直排列的div水平线链接,并简单地看看哪个具有悬停状态)就像Tim Down的想法以上,它的工作速度非常快。可悲的是,在KDE上的Chrome 32上无效。
jsfiddle.net/5XzeE/4 /
答案 8 :(得分:1)
您无需移动鼠标即可获取光标的位置。此位置也会报告 mousemove 以外的事件。以下是点击事件:
document.body.addEventListener('click',function(e)
{
console.log("cursor-location: " + e.clientX + ',' + e.clientY);
});
答案 9 :(得分:1)
这是我的解决方案。它导出可以在任何地方使用的 window.currentMouseX 和 window.currentMouseY 属性。它首先使用悬停的元素(如果有)的位置,然后使用鼠标的移动来设置正确的值。
(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来源: https://github.com/ocproducts/composr/commit/a851c19f925be20bc16bfe016be42924989f262e#diff-b162dc9c35a97618a96748639ff41251R1202
答案 10 :(得分:0)
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;
}
答案 11 :(得分:0)
重复@SuperNova's answer,这是一种使用ES6类的方法,可以在回调中保持this
的上下文正确:
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));
&#13;
答案 12 :(得分:0)
我认为我可能有一个不计div和像素的合理解决方案。.lol
仅使用动画帧或函数的时间间隔。尽管只是启动一次,您仍然需要一次鼠标事件,但是从技术上讲,您可以将鼠标定位在任意位置。
本质上,我们始终在没有鼠标移动的情况下跟踪虚拟div。
// create a div(#mydiv) 1px by 1px set opacity to 0 & position:absolute;
下面是逻辑。
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);
}
答案 13 :(得分:0)
不是鼠标位置,但是,如果要查找当前光标位置(用于获取最后键入的字符等用例),则在以下代码段中可以正常工作。
这将为您提供与文本内容相关的光标索引。
window.getSelection().getRangeAt(0).startOffset