如何检测鼠标何时离开窗口?

时间:2009-05-28 21:28:37

标签: javascript browser mouse

我希望能够检测到鼠标何时离开窗口,以便在用户的鼠标位于其他地方时阻止事件被触发。

关于如何做到这一点的任何想法?

19 个答案:

答案 0 :(得分:91)

在html页面上实现拖放行为时,通常需要这种行为。下面的解决方案在MS Windows XP机器上的IE 8.0.6,FireFox 3.6.6,Opera 10.53和Safari 4上进行了测试。
首先是Peter-Paul Koch的一个小功能;跨浏览器事件处理程序:

function addEvent(obj, evt, fn) {
    if (obj.addEventListener) {
        obj.addEventListener(evt, fn, false);
    }
    else if (obj.attachEvent) {
        obj.attachEvent("on" + evt, fn);
    }
}

然后使用此方法将事件处理程序附加到文档对象mouseout事件:

addEvent(document, "mouseout", function(e) {
    e = e ? e : window.event;
    var from = e.relatedTarget || e.toElement;
    if (!from || from.nodeName == "HTML") {
        // stop your drag event here
        // for now we can just use an alert
        alert("left window");
    }
});

最后,这是一个html页面,其中嵌入了用于调试的脚本:

<html>
<head>
<script type="text/javascript">
function addEvent(obj, evt, fn) {
    if (obj.addEventListener) {
        obj.addEventListener(evt, fn, false);
    }
    else if (obj.attachEvent) {
        obj.attachEvent("on" + evt, fn);
    }
}
addEvent(window,"load",function(e) {
    addEvent(document, "mouseout", function(e) {
        e = e ? e : window.event;
        var from = e.relatedTarget || e.toElement;
        if (!from || from.nodeName == "HTML") {
            // stop your drag event here
            // for now we can just use an alert
            alert("left window");
        }
    });
});
</script>
</head>
<body></body>
</html>

答案 1 :(得分:39)

如果你正在使用jQuery那么这个简短而又甜蜜的代码怎么样 -

$(document).mouseleave(function () {
    console.log('out');
});

只要鼠标不在您的页面中,就会触发此事件。只需更改功能即可执行任何操作。

你也可以使用:

$(document).mouseenter(function () {
    console.log('in');
});

当鼠标再次回到页面时触发。

来源:https://stackoverflow.com/a/16029966/895724

答案 2 :(得分:24)

这对我有用:

addEvent(document, 'mouseout', function(evt) {
  if (evt.toElement == null && evt.relatedTarget == null) {
    alert("left window");
  }
});

答案 3 :(得分:9)

为了检测mouseleave而不考虑滚动条和自动完成字段或检查:

document.addEventListener("mouseleave", function(event){

  if(event.clientY <= 0 || event.clientX <= 0 || (event.clientX >= window.innerWidth || event.clientY >= window.innerHeight))
  {

     console.log("I'm out");

  }
});

条件解释:

event.clientY <= 0  is when the mouse leave from the top
event.clientX <= 0  is when the mouse leave from the left
event.clientX >= window.innerWidth is when the mouse leave from the right
event.clientY >= window.innerHeight is when the mouse leave from the bottom

答案 4 :(得分:5)

这些答案都不适合我。我现在正在使用:

document.addEventListener('dragleave', function(e){

    var top = e.pageY;
    var right = document.body.clientWidth - e.pageX;
    var bottom = document.body.clientHeight - e.pageY;
    var left = e.pageX;

    if(top < 10 || right < 20 || bottom < 10 || left < 10){
        console.log('Mouse has moved out of window');
    }

});

我将其用于拖放文件上传小部件。它不是绝对准确的,当鼠标离窗口边缘一定距离时触发。

答案 5 :(得分:3)

我已经尝试了以上所有内容,但似乎没有按预期工作。经过一些研究后,我发现 e.relatedTarget html ,只是在鼠标退出窗口之前

所以......我最终得到了这个:


document.body.addEventListener('mouseout', function(e) {
    if (e.relatedTarget === document.querySelector('html')) {
        console.log('We\'re OUT !');
    }
});

如果您发现任何问题或改进,请与我们联系!

2019年更新

(如user1084282所见)

document.body.addEventListener('mouseout', function(e) {
    if (!e.relatedTarget && !e.toElement) {
        console.log('We\'re OUT !');
    }
});

答案 6 :(得分:3)

这是 2021 年的答案:

您可以在 mouseleave 标签中使用 mouseenter(和 html 来检测输入)(在 Chrome 91 和 Firefox 90 中测试)

在下面的 Snippet 中尝试,将鼠标悬停在其中。

document.documentElement.addEventListener('mouseleave', () => console.log('out'))
document.documentElement.addEventListener('mouseenter', () => console.log('in'))

答案 7 :(得分:3)

使用onMouseLeave事件可防止冒泡,并允许您轻松检测鼠标何时离开浏览器窗口。

<html onmouseleave="alert('You left!')"></html>

http://www.w3schools.com/jsref/event_onmouseleave.asp

答案 8 :(得分:3)

我收回我说的话。有可能的。我写了这段代码,效果很好。

window.onload = function() {

    $span = document.getElementById('text');

    window.onmouseout = function() {
        $span.innerHTML = "mouse out";  
    }

    window.onmousemove = function() {
        $span.innerHTML = "mouse in";   
    }

}

适用于chrome,firefox,opera。 Aint在IE中测试但是假设它有效。

修改。 IE总是会引起麻烦。要使其在IE中工作,请将窗口中的事件替换为文档:

window.onload = function() {

    $span = document.getElementById('text');

    document.onmousemove = function() {
        $span.innerHTML = "mouse move";
    }

    document.onmouseout = function() {
        $span.innerHTML = "mouse out";
    }

}

将它们组合起来用于交叉浏览器踢屁股光标检测o0:P

答案 9 :(得分:2)

应用此css:

html
{
height:100%;
}

这可以确保html元素占据窗口的整个高度。

应用此jquery:

$("html").mouseleave(function(){
 alert('mouse out');
});

鼠标悬停和鼠标移出的问题在于,如果将html鼠标移出/移出子元素,它将引发该事件。当鼠标移动到子元素时,我给 的函数不是 。只有当您将鼠标移出窗口

时才会设置它

只是让你知道你可以在用户迷上窗口时这样做:

$("html").mouseenter(function(){
  alert('mouse enter');
});

答案 10 :(得分:2)

请参见mouseovermouseout

var demo = document.getElementById('demo');
document.addEventListener("mouseout", function(e){demo.innerHTML="?";});
document.addEventListener("mouseover", function(e){demo.innerHTML="?";});
div { font-size:80vmin; position:absolute;
      left:50%; top:50%; transform:translate(-50%,-50%); }
<div id='demo'>?</div>

答案 11 :(得分:1)

$(window).mouseleave(function(event) {
  if (event.toElement == null) {
    //Do something
  }
})

这可能有点hacky但它​​只会在鼠标离开窗口时触发。我一直在捕捉儿童事件,这解决了它

答案 12 :(得分:1)

$(window).mouseleave(function() {
 alert('mouse leave');
});

答案 13 :(得分:1)

也许如果你经常在body标签中听OnMouseOver,那么当事件没有发生时回调,但是,正如Zack所说,这可能非常难看,因为并非所有的浏览器都以相同的方式处理事件,那里即使是在同一页面上的div上,你甚至有可能丢失MouseOver。

答案 14 :(得分:0)

我没有对此进行测试,但我的直觉是在body标签上进行OnMouseOut函数调用。

答案 15 :(得分:0)

也许这会帮助一些后来到这里的人。 window.onblurdocument.mouseout

在以下情况下触发

window.onblur

  • 您使用Ctrl+TabCmd+Tab切换到另一个窗口。
  • 您在文档检查器上聚焦(而不仅仅是鼠标悬停)。
  • 您可以切换桌面。

基本上任何时候浏览器选项卡失去焦点。

window.onblur = function(){
    console.log("Focus Out!")
}
在以下情况下触发

document.mouseout

  • 将光标移动到标题栏上。
  • 您使用Ctrl+TabCmd+Tab切换到另一个窗口。
  • 您打开将光标移动到文档检查器。

基本上,当光标离开文档时,无论如何。

document.onmouseleave = function(){
    console.log("Mouse Out!")
}

答案 16 :(得分:0)

这对我有用。这里有一些答案的组合。我只包含了一次显示模型的代码。点击其他任何地方时,模型都会消失。

<script>
    var leave = 0
    //show modal when mouse off of page
    $("html").mouseleave(function() {
       //check for first time
       if (leave < 1) {
          modal.style.display = "block";
          leave = leave + 1;
       }
    });

    // Get the modal with id="id01"
       var modal = document.getElementById('id01');

    // When the user clicks anywhere outside of the modal, close it
       window.onclick = function(event) {
          if (event.target == modal) {
             modal.style.display = "none";
          }
       }
</script>

答案 17 :(得分:0)

我一个接一个地尝试,发现可接受的答案真的有效 !

https://stackoverflow.com/a/3187524/985399

我跳过了旧的浏览器,所以我缩短了代码以在现代浏览器IE9 +上工作:

  val df = spark.read.format(source = "csv")
    .option("header", true)
    .option("delimiter", ",")
    .option("inferSchema", true)
    .load("groupby.dat")

  import spark.implicits._

  //collect data for each key into a data frame
  val uniqueIds = df.select("id").distinct().map(x => x.mkString.toInt).collect()
  // List buffer to hold separate data frames
  var dataframeList: ListBuffer[org.apache.spark.sql.DataFrame] = ListBuffer()
  println(uniqueIds.toList)

  // filter data
  uniqueIds.foreach(x => {
    val tempDF = df.filter(col("id") === x)
    dataframeList += tempDF
  })

  //show individual data frames
  for (tempDF1 <- dataframeList) {
    tempDF1.show()
  }

在这里您看到browser support

但是"mouseout" trigg on all elements in document。通过 mouseleave (IE5.5 + se链接)消除了防止其发生的代码。

下面的代码在文档外部的 mouse-leave drag-release 上均可工作:

    document.addEventListener("mouseout", function(e) {
        let t = e.relatedTarget || e.toElement;
        if (!t || t.nodeName == "HTML") {
          console.log("left window");
        }
    });

var x = 0 document.onmouseleave = function(e) { console.log(x++) }上没有该事件,因为Windows滚动条可能会缩小该事件并取消滚动。

答案 18 :(得分:-2)

这适用于chrome,

$(document).bind('dragleave', function (e) {
    if (e.originalEvent.clientX == 0){
        alert("left window");
    }
});