페이지 종료 이벤트 차단


117

내 시스템 내에서 페이지를 편집 할 때 사용자가 다른 웹 사이트로 이동하기로 결정할 수 있으며 그렇게하면 저장하지 않은 모든 편집 내용이 손실 될 수 있습니다.

다른 페이지로 이동하려는 모든 시도를 가로 채고 사용자가 현재 작업을 잃을 수 있으므로 이런 일이 발생하기를 원하는지 확인하고 싶습니다.

Gmail은이 작업을 매우 유사한 방식으로 수행합니다. 예를 들어 새 이메일을 작성하고 메시지 본문에 입력을 시작하고 주소 표시 줄에 새 위치를 입력합니다 (예 : twitter.com 또는 기타). "확실합니까?"라는 메시지가 표시됩니다.

이것을 복제하는 방법에 대한 아이디어? IE8을 타겟팅하고 있지만 FF 및 Chrome 과도 호환되고 싶습니다.


답변:


154

Ghommey의 답변과 비슷하지만 IE 및 Firefox의 이전 버전도 지원합니다.

window.onbeforeunload = function (e) {
  var message = "Your confirmation message goes here.",
  e = e || window.event;
  // For IE and Firefox
  if (e) {
    e.returnValue = message;
  }

  // For Safari
  return message;
};

1
첫 번째 줄 (var message = ...)을 설명해 주시겠습니까? 나는 그 쉼표와 두 번째 표현이 무엇을하고 있는지 모른다.
mtmurdock

7
@mtmurdock 여러 변수를 선언하는 자바 스크립트 구문입니다. var foo, bar;과 동일var foo; var bar;
T 응우 엔

4
@mtmurdock, 두 번째 문 " var e = e || window.event;" e 를 매개 변수 e (진실이면) 또는 window.event 같게 설정한다는 의미입니다 . 매개 변수 e 가 null이면 사실이 아닙니다 .
T Nguyen

3
@Blieque addEventListener는 IE8에서 지원되지 않습니다. 질문을 읽지 않고 사람들의 답변을 편집하지 마십시오.
Eli Gray

2
Chrome에서 더 이상 작동하지 않음 (지원 중단됨) : developers.google.com/web/updates/2016/04/…
Micha Schwab

25

이 기사를 참조하십시오. 당신이 찾고있는 기능은 onbeforeunload입니다.

샘플 코드 :

  <script language="JavaScript">
  window.onbeforeunload = confirmExit;
  function confirmExit()
  {
    return "You have attempted to leave this page.  If you have made any changes to the fields without clicking the Save button, your changes will be lost.  Are you sure you want to exit this page?";
  }
</script>

2
사용자가 "이 페이지에 머무르기"대신 "이 페이지 나가기"옵션을 선택했는지 확인할 수있는 방법이 있습니까?
Shilpa Soni

@ShilpaSoni 당신은 곧 후속 언로드 이벤트, developer.mozilla.org/en-US/docs/Web/API/Window/unload_event를 얻을 수 있지만 동기식 방법이 있다고 생각하지 않습니다.
scipilot

6

성가신 확인 팝업 대신 저장되지 않은 데이터를 서버에 성공적으로 게시하기 위해 약간 (밀리 초 단위) 만 남겨 두는 것이 좋을 것입니다 . 서버에 다음과 같이 더미 텍스트를 작성하여 내 사이트를 관리했습니다.

window.onbeforeunload=function(e){
  // only take action (iterate) if my SCHEDULED_REQUEST object contains data        
  for (var key in SCHEDULED_REQUEST){   
    postRequest(SCHEDULED_REQUEST); // post and empty SCHEDULED_REQUEST object
    for (var i=0;i<1000;i++){
      // do something unnoticable but time consuming like writing a lot to console
      console.log('buying some time to finish saving data'); 
    };
    break;
  };
}; // no return string --> user will leave as normal but data is send to server

편집 : Synchronous_AJAXjquery 로 수행하는 방법 참조


팝업에 대한 대안이 마음에 듭니다. 제안 해 주셔서 감사합니다, 레미.
Chris Ballance 2012 년

2
그것은 절대적으로 말이되지 않습니다 -1. 자바 스크립트는 스레드되지 않습니다. postRequest를 수행 한 다음 아무도 아무것도하지 못하게하지 않고 사이트 계산을 일시 중지하는 것입니다 (계산 일시 중지 전에 이미 전송 된 postRequest 포함).
fmsf

그리고 그것이 정확히 작동하는 이유입니다. 실제로 사후 요청은 계산이 일시 중지되기 전에 전송되었지만 실제로 남겨지기 전에 페이지를 약간 차단하면 브라우저 클라이언트 (JavaScript가 아님)가이 요청을 제대로 전송하는 데 충분한 시간을 보장합니다. . 요청 만 보내고 (차단하지 않고) 즉시 페이지를 나가면 요청이 항상 전송되는 것은 아닙니다.
Remi

6
나는 그것을 프로덕션에서 사용하지 않을 것입니다. console.log는 크로스 브라우저가 아닙니다. 각 postRequest는 이전 요청의 지연으로 어려움을 겪습니다 (즉, 루프 * 예약 된 요청 동안 페이지가 중단됨을 의미합니다). 요청은 병렬로 시작되지 않습니다. 실제로 요청을 보낼 것이라는 보장은 없습니다. 이 문제에 직면해야한다면 요청이 하나만 있으면 동기식 아약스 요청을 사용합니다. 여러 요청으로 비동기 ajax 요청과 요청의 콜백에서 결과 (성공 또는 오류)를 확인하는 루프를 사용합니다.
framp 2009 년

나는 console.log가 크로스 브라우저가 아니며 동기식 Ajax 요청 이 실제로 선호되는 솔루션이어야한다는 것을 몰랐습니다 (단일 요청의 경우). 언급 된 SCHEDULED_REQUEST것은 데이터 버퍼와 같이 서버로 보내야하는 긴급하지 않은 정보를 누적하여 여러 요청을 효과적으로 하나로 결합하는 객체입니다 (물론 이러한 요청의 URL은 동일합니다). 언로드하기 전에 동기식 Ajax 요청을 사용하면 말했듯이 브라우저 간 문제를 해결할 수 있습니다. 소중한 의견 주셔서 감사합니다!
레미

0

필요한 모든 데이터를 작성하지 않은 사용자가 있습니다.

<cfset unloadCheck=0>//a ColdFusion precheck in my page generation to see if unload check is needed
var erMsg="";
$(document).ready(function(){
<cfif q.myData eq "">
    <cfset unloadCheck=1>
    $("#myInput").change(function(){
        verify(); //function elsewhere that checks all fields and populates erMsg with error messages for any fail(s)
        if(erMsg=="") window.onbeforeunload = null; //all OK so let them pass
        else window.onbeforeunload = confirmExit(); //borrowed from Jantimon above;
    });
});
<cfif unloadCheck><!--- if any are outstanding, set the error message and the unload alert --->
    verify();
    window.onbeforeunload = confirmExit;
    function confirmExit() {return "Data is incomplete for this Case:"+erMsg;}
</cfif>
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.