使用JavaScript检测浏览器窗口是否移动?

17

这是一个演示...我只是好奇,你能检测窗口是否被移动吗?比如你在显示器上移动Firefox/Chrome/IE?我怀疑不行,但是我想看看,因为你可以检查调整大小和焦点/模糊的窗口。

您好,这是一篇有关于窗口移动检测的问题。作者想知道是否能够检测浏览器窗口是否被移动。尽管作者已经检查了窗口调整大小以及焦点/未聚焦状态的功能,但我认为不能检测窗口是否被移动。
5个回答

19

我只能想到这种(繁琐的)解决方法,每隔x毫秒检查一下window.screenXwindow.screenY是否有改变。

var oldX = window.screenX,
    oldY = window.screenY;

var interval = setInterval(function(){
  if(oldX != window.screenX || oldY != window.screenY){
    console.log('moved!');
  } else {
    console.log('not moved!');
  }

  oldX = window.screenX;
  oldY = window.screenY;
}, 500);

尽管我不建议这样做,因为它可能会很慢,而且我不确定所有浏览器是否都支持screenX和screenY。


1
screenXscreenY在IE中不受支持,但是有类似但不完全等效的window属性screenLeftscreenTop - Tim Down
聪明的技巧!我甚至从未想过。 - Oscar Godson
1
从IE9开始支持screenXscreenY来源)。 - Daniel Apt

10

这个问题的一个可能更优化的版本是只有在窗口外部移动时才检查,结合Harmen的答案:

var interval;
window.addEventListener("mouseout", function(evt){ 
  if (evt.toElement === null && evt.relatedTarget === null) {
    //if outside the window...
    if (console) console.log("out");
    interval = setInterval(function () {
      //do something with evt.screenX/evt.screenY
    }, 250);
  } else {
    //if inside the window...
    if (console) console.log("in");
    clearInterval(interval);
  }
});
如果使用jQuery,它可能会在这种情况下规范化screenX / Y,因此值得对此运行一些测试。 jQuery将使用此格式而不是addEventListener
$(window).on('mouseout', function () {});

如果您在Windows操作系统上通过alt+Space移动窗口,发现窗口大小调整被忽略,我建议通过keypress事件添加额外的检测级别。


2
好主意。你让我重新思考了我的问题。我将不再试图在用户拖动窗口时隐藏某些内容,而是在鼠标移出时隐藏它,并在鼠标移入时将其显示出来。 - vaughan
2
Windows用户可以通过键盘(Alt+Space)移动窗口。您的代码可能会忽略这些操作。 - CoolCmd
好的,知道了!有什么线索可以查找吗? - marksyzm
啊,我明白了,因为它没有运行间隔...现在正在想修复的方法。 - marksyzm
1
用户仍然可以通过键盘快捷键来操作窗口,例如在Windows上使用[Meta] + [Right'] || [Left]在不同的大小状态和监视器之间切换。 - John
你能告诉我按键事件是否同时注册到活动窗口吗?这些应该通过定位来传递。如果是这种情况,那么可能可以通过 preventDefault() 来取消该事件?我怀疑不行,但值得一试。 - marksyzm

8

关于第一个回答:我在生产代码中使用'poll window position'。这是一件非常轻量级的事情。每秒钟两次请求几个对象属性不会拖慢任何东西。跨浏览器的窗口位置由以下代码给出:

function get_window_x_pos()
{
   var winx;

   if(window.screenX)
      winx=window.screenX;
   else if(window.screenLeft)
      winx=window.screenLeft;

   return winx;
}

同样地,垂直位置也是如此。在我的代码中,我使用这个来触发一个AJAX事件到服务器去存储窗口的位置和大小,以便下一次打开时它能够出现在上一次的位置。(我可能很快会转向HTML5本地存储。)你可能想要解决的一个小问题是在拖动窗口时不生成虚假的更新。处理这个问题的方法是在第一次移动窗口时注册,只有当两次窗口位置的轮询返回相同的值时才触发更新。另一个复杂性是对于所有方向都允许调整大小的窗口。如果拖动左边或顶部,则DOM将给您一个调整大小事件,但名义上的窗口位置也会改变。


0

很遗憾,DOM仅通知窗口大小、光标位置、“焦点”和“失焦”等影响绘图的内容。由于移动窗口不一定需要重新绘制任何内容(在Javascript/Html引擎的意义上),因此DOM不需要知道它。


“不需要知道它”是错误的(否则就不会有人问了),但正确的是似乎没有办法解决(即使在2022年)。用户名奇怪。 - Glenn Maynard
移动窗口不需要更改任何内容。您的应用程序不应依赖于窗口位置。这也是一个隐私问题。如果您稍微搜索一下,我的用户名就有足够的上下文信息,不确定这与我的回答有什么关系。 - Qix - MONICA WAS MISTREATED

0
很遗憾,没有。虽然我找到了这个页面声称有这样的东西。我在IE、Chrome和FireFox中测试过了,但没有成功。

窗口对象的“move”事件只存在于Netscape 4中。 - Tim Down
@Tim Down:那是一个悲伤的浏览器.. 谢谢你的信息! - cambraca

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接