web-dev-qa-db-ja.com

マウスがウィンドウを離れたとき、どのように検出できますか?

マウスがウィンドウを離れたときを検出できるようにしたいので、ユーザーのマウスが他の場所にある間にイベントが発生するのを止めることができます。

これを行う方法のアイデアはありますか?

82
Matt

このタイプの動作は、通常、HTMLページにドラッグアンドドロップ動作を実装するときに必要です。以下のソリューションは、IE 8.0.6、FireFox 3.6.6、Opera 10.53、およびMS Windows上のSafari 4 XPマシン。
最初に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>
94
J Mills

JQueryを使用している場合、この短くて甘いコードはどうですか?

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

このイベントは、マウスがページにない場合にいつでもトリガーします。必要なことを行うように関数を変更するだけです。

また、次のものも使用できます。

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

マウスが再びページに戻ったときにトリガーします。

ソース: https://stackoverflow.com/a/16029966/895724

39
Mandeep Janjua

これは私のために働く:

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

スクロールバーとオートコンプリートフィールドを考慮せずに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
12
Daphoque

これらの答えはどれも私にとってはうまくいきませんでした。私は今使用しています:

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
Emmanuel

OnMouseLeaveイベントを使用すると、バブリングが防止され、マウスがブラウザーウィンドウから離れたときを簡単に検出できます。

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

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

4
Samy Bencherif

上記のすべてを試しましたが、期待どおりに機能するものはありません。少し調査した結果、e.relatedTargethtmlであることがわかりましたマウスがウィンドウを出る前にです。

だから...私はこれで終わりました:

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

問題や改善点を見つけたら教えてください!

2019更新

(ユーザー1084282が判明したように)

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

私が言ったことを取り戻します。可能です。私はこのコードを書きました、完璧に動作します。

window.onload = function() {

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

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

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

}

クロム、Firefox、オペラで動作します。 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

3
Ozzy

このCSSを適用します:

html
{
height:100%;
}

これにより、html要素がウィンドウの高さ全体を占めるようになります。

このjqueryを適用します。

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

マウスオーバーとマウスアウトの問題は、htmlの子要素にマウスオーバー/アウトすると、イベントが発生することです。私が与えた関数)は、子要素にマウスを合わせるとオフになりません。マウスをウィンドウの外に出したときだけオフになります

ユーザーがウィンドウ内でマウスを動かしたときにできることを知るためだけに:

$("html").mouseenter(function(){
  alert('mouse enter');
});
1
www139
$(window).mouseleave(function() {
 alert('mouse leave');
});
0
sandeep kumar

BodyタグでOnMouseOverを常にリッスンしていて、イベントが発生していないときにコールバックする場合がありますが、Zackが述べているように、これは非常にugい場合があります。同じページのdivの上にいても、MouseOverを失う可能性があります。

0
Pablo Albornoz

たぶん、これは後でここに来る人々の一部を助けるでしょう。 window.onblurおよびdocument.mouseout

window.onblurは次の場合にトリガーされます:

  • Ctrl+TabまたはCmd+Tabを使用して別のウィンドウに切り替えます。
  • (マウスオーバーだけでなく)ドキュメントインスペクターに集中します。
  • デスクトップを切り替えます。

基本的に、そのブラウザタブがフォーカスを失うときはいつでも。

window.onblur = function(){
    console.log("Focus Out!")
}

document.mouseoutは次の場合にトリガーされます:

  • カーソルをタイトルバーに移動します。
  • Ctrl+TabまたはCmd+Tabを使用して別のウィンドウに切り替えます。
  • 開いたら、カーソルをドキュメントインスペクターに移動します。

基本的に、カーソルがドキュメントから離れた場合。

document.onmouseleave = function(){
    console.log("Mouse Out!")
}
0
Jayant Bhawal
$(window).mouseleave(function(event) {
  if (event.toElement == null) {
    //Do something
  }
})

これは少しハッキーかもしれませんが、マウスがウィンドウを離れたときにのみトリガーされます。私は子供のイベントをキャッチし続け、これはそれを解決しました

0
Cekaleek

これはテストしていませんが、私の本能は、bodyタグでOnMouseOut関数呼び出しを行うことです。

0
Ender

これは私のために働いた。ここにいくつかの答えの組み合わせ。そして、モデルを示すコードを一度だけ含めました。そして、他の場所をクリックするとモデルは消えます。

<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>
0
Morgan Hayes

私は次々と試してみましたが、実際に動作する受け入れられた答えaboweを見つけました

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

古いブラウザーをスキップするため、IE9 +の最新のブラウザーで動作するようにコードを短くしました。

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

ここに ブラウザーサポート が表示されます

しかし、 「mouseout」はドキュメント内のすべての要素でトリガーされます 。それを防ぐコードは、mouseleave(IE5.5 + seリンク)によって排除されます。

次のコードは、ドキュメント外のmouse-leavedrag-releaseの両方で機能します:

var x = 0

document.onmouseleave = function(e) { console.log(x++) }

document.bodyにイベントを持たないでください。Windowsのスクロールバーがイベントを縮小し、スクロールを無効にする可能性があるためです。