마우스가 창을 벗어날 때 어떻게 감지합니까?


102

사용자의 마우스가 다른 곳에있는 동안 이벤트 발생을 중지 할 수 있도록 마우스가 창을 떠날 때를 감지 할 수 있기를 원합니다.

이를 수행하는 방법에 대한 아이디어가 있습니까?


1
이 beeker exit-intent github 라이브러리를 확인하십시오. 훌륭합니다. github.com/beeker1121/exit-intent-popup
raksheetbhat

mouseleave 를 사용 하여 mouseout이하 는 것처럼 모든 요소에서 실행 을 방지 하십시오 . 아주 좋은 설명 및 지원 : developer.mozilla.org/en-US/docs/Web/API/Element/…

문서에 이벤트를 설정하십시오. Windows 스크롤바가 본문을 축소하는 것 같습니다.

답변:


100

내 대답이 많이 낡았 음을 명심하십시오.

이러한 유형의 동작은 일반적으로 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>

window.event를 사용 하여이 이벤트를 얻는 문제를 해결했습니다. 감사!
Jay

크롬에서 마우스를 누르지 않으면 실행되지 않는 것 같습니다. 크롬에서 마우스를 눌렀을 때 실행됩니다. 일관되지 않은 행동처럼 보입니다.
antony.trupe 2014 년

5
다른 HTML 요소가 창을 채우면 작동하지 않습니다.
엠마뉴엘

이 솔루션의 문제점은 사용자가 스크롤러를 사용하려고해도 왼쪽 창에 경고를 표시한다는 것입니다. 이 문제에 대한 해결책을 여기에 게시 했지만 여전히 해결해야 할 문제가 하나 있습니다 (링크 참조).
JohnyFree

1
사용하다 문서의 요소에 대한 실행을 방지 mouseout 대신 mouseleave 를 . 매우 설명 좋은는 IE5.5 ... 작동 developer.mozilla.org/en-US/docs/Web/API/Element/...

42

jQuery를 사용하는 경우이 짧고 달콤한 코드는 어떻습니까?

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

이 이벤트는 원하는대로 페이지에 마우스가 없을 때마다 트리거됩니다. 원하는대로 기능을 변경하면됩니다.

다음을 사용할 수도 있습니다.

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

마우스가 페이지로 다시 들어갈 때 트리거합니다.

출처 : https://stackoverflow.com/a/16029966/895724


mouseleave가 작동하지만 검사 요소가 열리면 실행됩니다. 어떻게 방지합니까? 생각?
Pankaj Verma

이 기술은 Chrome 15 ~ 56 (현재 버전)에서는 안정적이지 않습니다. 그러나 그것은 Firefox에서 매우 잘 작동합니다. 참조 : stackoverflow.com/questions/7448468/…
Tremours

mouseleave가 예상보다 훨씬 더 많이 발사되는 것 같습니다.
알렉산더

또한 창이 백그라운드에 있고 (브라우저가 초점이 맞지 않음) 마우스가 창에 들어가면 실행됩니다 (Chrome 61 / macOS10.11)
CodeBrauer 2017

1
@Skeets (및 향후 독자)이 문제는 2019 년 2 월 14 일
Xandor

27

이것은 나를 위해 작동합니다.

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

9
무엇입니까 addEvent?
Yi Jiang


4
ie8에서는 relatedTarget이 정의되지 않았고 ie9 + 및 firefox에서는 toElement가 정의되지 않았습니다. 왜냐하면 올바른 평가는 다음과 같습니다. if ((evt.relatedTarget === null) || (evt.toElement === null)) {
carlos

1
술어는보다 간결 할 수 있습니다.if (!evt.toElement && !evt.relatedTarget)
Pavel Ye

20

스크롤 막대와 autcomplete 필드를 고려하지 않고 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

======================= 편집 ======================== ======

document.addEventListener ( "mouseleave")는 새 파이어 폭스 버전에서 실행되지 않는 것 같습니다. mouseleave는 body 또는 자식 요소와 같은 요소에 첨부되어야합니다.

대신 사용하는 것이 좋습니다

document.body.addEventListener("mouseleave")

또는

window.addEventListener("mouseout")

때때로 해고되지 않습니다. 커서 이동에 의해 트리거 된 포인트 스트림의 한 지점이 테두리를 조준하고 커서의 크기가 조정될 때와 같은 이음새가 실패합니다.
Ivan Borshchov

@ user3479125, 내 스 니펫에서도 시도해보고 if 문이 추가되지 않았을 때 문제가 남아 있는지 확인할 수 있습니까? 스크롤 막대를 고려하지만 자동 완성 또는 검사로 테스트하지 않았습니다. stackoverflow.com/a/56678357/985399

7

onMouseLeave 이벤트를 사용하면 버블 링을 방지하고 마우스가 브라우저 창을 벗어날 때 쉽게 감지 할 수 있습니다.

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

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


환상적입니다! 지원은 IE5.5 +입니다 ... 또한 작동합니다 : document.onmouseleave = function() { alert('You left!') };본문을 축소하는 스크롤 막대를 실행하는 document.body를 사용하지 마십시오! 요소에 대한 화재를 방지하는 코드는 필요하지 않습니다. 좋은 설명 : developer.mozilla.org/en-US/docs/Web/API/Element/…

6

이 답변 중 어느 것도 나를 위해 일하지 않았습니다. 나는 지금 사용하고 있습니다 :

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');
    }

});

드래그 앤 드롭 파일 업로드 위젯에 사용하고 있습니다. 절대적으로 정확하지는 않으며 마우스가 창 가장자리에서 특정 거리에 도달하면 트리거됩니다.


마우스 움직임이 "충분히 빠르면"이 기능이 트리거되지 않는 경우가 있습니다.
John Weisz

@JohnWeisz 네, 당신이 옳다고 생각합니다. 이 스크립트를 한동안 사용해 왔지만 잘 작동합니다.
Emmanuel

6

위의 모든 것을 시도했지만 예상대로 작동하지 않는 것 같습니다. 약간의 조사 끝에 나는 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 !');
    }
});

2
크롬에서 나를 위해 일하지 않습니다. relatedTarget마우스가 창을 떠날 때 null입니다. @ user1084282의 대답에 의해 영감이로 변경 : if(!e.relatedTarget && !e.toElement) { ... }그것은 작동

if(!e.relatedTarget && !e.toElement)실제 답변의 조건 대신 사용하면 Chrome, Firefox 및 IE Edge에서 제대로 작동하는지 확인합니다 . 마우스가 문서 본문을 떠나는 것을 감지합니다.
Haijerome 2019

document.body에 이벤트가 발생하지 마십시오. 창 스크롤바가 스크롤바를 축소하고 스크롤을 벗어날 수 있기 때문입니다. 그리고 왜 당신은 'mouseleave'를 가질 수있을 때 모든 버블 요소에서 발동하는 'mouseout'을 가지고 있습니까? developer.mozilla.org/en-US/docs/Web/API/Element/…

2

나는 내가 말한 것을 되 돌린다. 것이 가능하다. 이 코드를 작성하고 완벽하게 작동합니다.

window.onload = function() {

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

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

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

}

크롬, 파이어 폭스, 오페라에서 작동합니다. IE에서 테스트되지 않았지만 작동한다고 가정합니다.

편집하다. IE는 항상 문제를 일으 킵니다. IE에서 작동하도록하려면 창에서 문서로 이벤트를 바꿉니다.

window.onload = function() {

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

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

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

}

crossbrowser kick ass cursor detection o0 : P를 위해 그것들을 결합하십시오.


이것이 페이지의 요소와 함께 얼마나 잘 작동하는지 테스트 했습니까? 자체 'onmouseover / out'이벤트가있는 요소가 잠재적으로 버블 링을 취소하고이 기능을 중단 할 수 있다고 생각합니다.
Dan Herbert

1
오지, Dan은 이벤트 전파를 중지하는 요소가 이벤트가 문서 / 창에 도달하지 못하게하여 솔루션을 비효율적으로 만든다고 설명하려고합니다.
James

방금 자체 onmousemove 및 onmouseout 이벤트로 다른 요소로 테스트했지만 여전히 잘 작동합니다.
Ozzy

2
예,하지만 다시 이벤트 전파에 대해 이야기하고 있습니다. 의도적으로 EVENT.stopPropagation () (IE의 경우 EVENT.cancelBubble = true)을 사용하여 이벤트 전파를 중지하면 문서 / 창에 버블 링되지 않습니다 ...이 문제를 해결하기 위해이를 지원하는 브라우저에서 이벤트 캡처를 사용할 수 있습니다. .
James

JS에서 변수를 선언하려면 'var'를 사용해야합니다. 이제 $ span 변수는 암시 적 전역이므로 원하는 것이 아닐 수 있습니다. 또한 의도적이지 않은 경우 변수 이름에 $가 필요하지 않습니다.
Jani Hartikainen 2010

2

이 CSS를 적용하십시오.

html
{
height:100%;
}

이렇게하면 html 요소가 창의 전체 높이를 차지하게됩니다.

이 jquery를 적용하십시오.

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

mouseover 및 mouseout의 문제는 html에서 자식 요소에 마우스를 가져 가면 이벤트가 시작된다는 것입니다. 내가 준 기능 은 자식 요소에 마우스를 놓을 때 설정 되지 않습니다 . 창 밖으로 / 마우스를 내밀 때만 설정됩니다.

사용자가 창에서 마우스를 움직일 때 할 수 있다는 것을 알기 위해 :

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

2
"나는 자바 스크립트가 동등한 기능을 가지고 있다고 생각하지 않는다"라는 말은, 당신은 jQuery가 자바 스크립트 함수 라이브러리이고 jQuery가 자바 스크립트로 쓰여졌다는 것을 모른다는 것을 의미합니다.
Milche Patern 2016

2
@MilchePatern 거의 2 년 전에이 답변을 썼습니다. 나는 그 당시 더 무지했고 jQuery에서 수행되는 모든 작업이 순수 JavaScript에서 수행 될 수 있다는 사실을 깨닫지 못했습니다. 나는 대답을 업데이트 할 것이다 ...
www139

2

나는 차례로 시도했고 당시 최고의 답변을 찾았습니다.

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");
        }
    });

document.write("<br><br>PROBLEM<br><br><div>Mouseout trigg on HTML elements</div>")

여기에서 브라우저 지원이 표시됩니다.

내가 생각하기에 꽤 짧았 어

그러나 문서의 모든 요소에 대한 "마우스 아웃"트리거 때문에 문제가 여전히 남아 있습니다. .

이를 방지하려면 mouseleave를 사용 하십시오. (IE5.5 +)를 사용하십시오. 링크에서 좋은 설명을 참조하십시오.

다음 코드는 내부 또는 외부에있는 요소 내부의 요소를 트리거하지 않고 작동합니다. 문서 외부로 끌어서 놓아보십시오.

var x = 0

document.addEventListener("mouseleave", function(e) { console.log(x++) 
})

document.write("<br><br>SOLUTION<br><br><div>Mouseleave do not trigg on HTML elements</div>")

모든 HTML 요소에 이벤트를 설정할 수 있습니다. 이벤트를 설정하지 마십시오 document.body. 스크롤을 원할 때 마우스 포인터가 스크롤 막대 위에있을 때 창 스크롤바가 본문을 축소하고 발동 될 수 있지만 mouseLeave 이벤트를 그 위에 트리거하지 않습니다. document예에서와 같이 대신 설정하십시오 .


1

본문 태그에서 OnMouseOver를 지속적으로 듣고 있다면 이벤트가 발생하지 않을 때 콜백 할 수 있지만 Zack이 언급했듯이 모든 브라우저가 동일한 방식으로 이벤트를 처리하는 것은 아니기 때문에 매우 추할 수 있습니다. 같은 페이지에서 div 위에 있어도 MouseOver를 잃을 가능성이 있습니다.


답변이 아닙니다

1

아마도 이것은 나중에 여기 오는 사람들 중 일부를 도울 것입니다. window.onblurdocument.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!")
}

"그 브라우저 탭이 포커스를 잃을 때마다." .. IE 이전 버전에서 'blur'이벤트는 다른 요소가 포커스를받을 때 / 후에 DOM이 강제됩니다. gooChrome의 경우 요소 자체가 포커스를 잃을 때입니다.
Milche Patern 2016

똑똑한 사용 window.onblur도. +1
Redwolf 프로그램

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

이것은 약간 엉망 일 수 있지만 마우스가 창을 떠날 때만 트리거됩니다. 나는 계속해서 어린이 이벤트를 잡아서 해결했습니다.



1

이것은 나를 위해 일했습니다. 여기에 몇 가지 답변의 조합입니다. 그리고 모델을 보여주는 코드를 한 번만 포함했습니다. 다른 곳을 클릭하면 모델이 사라집니다.

<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>

질문에 어떤 jQuery를 태그 없었다
mrReiha

jQuery는 최신 브라우저 IE9 + 및 나머지에서 작동하는 내 답변에 비해 많은 코드입니다. 이 답변을 기반으로하지만 훨씬 더 짧습니다. stackoverflow.com/a/3187524/985399

1

mouseover및을 참조하십시오 mouseout.

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>


0

나는 이것을 테스트하지 않았지만 내 본능은 body 태그에서 OnMouseOut 함수 호출을 수행하는 것입니다.


-2

이것은 크롬에서 작동합니다.

$(document).bind('dragleave', function (e) {
    if (e.originalEvent.clientX == 0){
        alert("left window");
    }
});
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.