OnBeforeUnload 대화 상자를 재정의하고 내 대화 상자로 바꾸려면 어떻게해야합니까?


346

저장하지 않은 변경 사항이 페이지를 떠나기 전에 사용자에게 경고해야합니다 (일반적인 문제).

window.onbeforeunload=handler

이것은 작동하지만 내 텍스트를 감싸는 자극적 인 표준 메시지가있는 기본 대화 상자가 나타납니다. 표준 메시지를 완전히 대체해야하므로 텍스트가 명확하거나 jQuery를 사용하여 전체 대화 상자를 모달 대화 상자로 바꾸십시오.

지금까지 나는 실패했고 대답이있는 사람을 찾지 못했습니다. 가능합니까?

내 페이지의 자바 스크립트 :

<script type="text/javascript">   
   window.onbeforeunload=closeIt;
</script>

closeIt () 함수 :

function closeIt()
{
  if (changes == "true" || files == "true")
  {
      return "Here you can append a custom message to the default dialog.";
  }
}

jQuery와 jqModal을 사용하여 이런 종류의 작업을 시도했습니다 (사용자 정의 확인 대화 상자 사용).

$(window).beforeunload(function() {
        confirm('new message: ' + this.href + ' !', this.href);
        return false;
    });

작동하지 않습니다-beforeunload 이벤트에 바인딩 할 수 없습니다.


1
현재 코드의 예와 코드를 제공 할 수 있습니까?
Owen

오웬이 맞습니다. 그리고 그 이유는 보안입니다. 페이지가 언로드되는 것을 방지하는 것은 웹 양식 등에 유용하지만 악의적 인 사이트에서 쉽게 악용하여 사용자가 페이지에 머 무르도록 속일 수 있습니다. 그렇기 때문에 웹 브라우저가 표준 메시지를 구현하고 사용자 지정 텍스트를 삽입하기위한이 메커니즘이 있습니다.
pluckyglen 2009

자세한 내용은 여기를 참조하십시오 : stackoverflow.com/questions/140460
Ben McIntyre 2013


1
크롬에서 불가능, 참조 : stackoverflow.com/questions/37782104/…
Abhijeet

답변:


300

에 대한 기본 대화를 수정할 수 없습니다 onbeforeunload 가장 좋은 방법은이 사용하는 것입니다.

window.onbeforeunload = function() {
    return 'You have unsaved changes!';
}

다음 은 Microsoft 의 참조입니다 .

문자열이 window.event의 returnValue 속성에 할당되면 사용자에게 현재 페이지를 유지하고 할당 된 문자열을 유지하는 옵션을 제공하는 대화 상자가 나타납니다. 대화 상자에 나타나는 "이 페이지에서 벗어나시겠습니까? ... 계속하려면 확인을 누르거나 현재 페이지에 남아 있으려면 취소를 누르십시오."대화 상자에 나타나는 기본 설명을 제거하거나 변경할 수 없습니다.

문제는 다음과 같습니다.

  1. onbeforeunload이 호출 되면 핸들러의 반환 값을로 사용 window.event.returnValue합니다.
  2. 그런 다음 반환 값을 문자열로 구문 분석합니다 (널이 아닌 경우).
  3. 때문에 false문자열로 구문 분석, 대화 상자는 적절한 통과되는 화재 것 true/을 false.

그 결과, 할당하는 방법이있을 것 같지 않습니다되어 false하는 onbeforeunload기본 대화에서 그것을 방지하기 위해.

jQuery에 대한 추가 참고 사항 :

  • jQuery에서 이벤트를 설정 하면 다른 이벤트도 발생할 있으므로 문제가 될 수 있습니다 onbeforeunload. 언로드 이벤트가 발생하기를 원한다면 일반 JavaScript를 사용하십시오.
  • jQuery에는 단축키가 onbeforeunload없으므로 일반 bind구문 을 사용해야 합니다.

    $(window).bind('beforeunload', function() {} );

편집 09/04/2018 : chrome-51부터 onbeforeunload 대화 상자의 사용자 정의 메시지가 더 이상 사용되지 않습니다 (참고 : 릴리스 노트 )


20
파이어 폭스에서 작동하지 않는 끝에 주어진 JQuery 예제를 발견했습니다. 대신 간단한 방법을 사용하십시오. window.onbeforeunload = function () {...}
jb.

21
Firefox의 대화 상자에서 텍스트를 사용자 정의 할 수 없도록 최근에 변경되었습니다. bugzilla.mozilla.org/show_bug.cgi?id=588292
David Hammond

15
그러나 페이스 북은 어떻게 사용자 정의 대화 상자를 제공합니까? 예를 들어, 메시지 페이지로 이동하여 친구의 메시지에 회신 한 다음 보내기를 클릭하기 전에 다른 링크를 클릭하십시오. 당신은 사용자 정의 대화 상자 팝업을 볼 수 있습니다
Varun

20
@Varun-오래된 뉴스이지만 Facebook은 모든 앵커의 클릭 이벤트에 핸들러를 배치 할 수 있지만 브라우저에서 URL을 다시 쓰거나 창을 닫으면 제어 할 수없는 표준 방법으로 돌아갑니다.
Tabloo Quijico

1
@Varun 또한 불가능한 방법이라는 답변이 답변으로 표시되고 150 개의 공감대를 가지고 있다는 사실에 놀랐습니다. 방금 FB의 맞춤 메시지는 사이트 내부의 링크를 통해서만 사용할 수 있습니다. 당신이 단순히 멀리 탐색하지 않으면 ...
Sébastien Richer

28

jQuery를 사용 하고 IE8, Chrome 및 Firefox에서 테스트 한 결과는 다음과 같습니다.

$(window).bind("beforeunload",function(event) {
    if(hasChanged) return "You have unsaved changes";
});

IE와 다른 브라우저 동작 사이에 차이점이 있으므로 프롬프트가 필요하지 않으면 아무것도 반환하지 않는 것이 중요합니다.


흥미로운 event.returnValue것은 IE에서 유일하게 "승인 된"방법입니다. IE "이 속성의 값은 Microsoft JScript return 문과 같이 함수가 반환 한 값보다 우선합니다"라고 말합니다. .. return(이벤트에서)와 event.returnValue.. 사이의 보장 된 상관 관계를 보는 것이 좋을 것입니다 .

21

어떤 상황에서는 상자에 대해 할 수있는 일이 없지만 링크를 클릭하는 사람을 가로 챌 수 있습니다. 나에게 이것은 대부분의 시나리오에서 노력할 가치가 있었고 대체로 언로드 이벤트를 남겼습니다.

표준 jQuery 대화 상자 대신 Boxy를 사용했으며 여기에서 사용할 수 있습니다 : http://onehackoranother.com/projects/jquery/boxy/

$(':input').change(function() {
    if(!is_dirty){
        // When the user changes a field on this page, set our is_dirty flag.
        is_dirty = true;
    }
});

$('a').mousedown(function(e) {
    if(is_dirty) {
        // if the user navigates away from this page via an anchor link, 
        //    popup a new boxy confirmation.
        answer = Boxy.confirm("You have made some changes which you might want to save.");
    }
});

window.onbeforeunload = function() {
if((is_dirty)&&(!answer)){
            // call this if the box wasn't shown.
    return 'You have made some changes which you might want to save.';
    }
};

다른 이벤트에 첨부하고 어떤 종류의 앵커를 클릭했는지 더 필터링 할 수는 있지만 이것은 나를 위해 작동하며 내가하고 싶은 일을하고 다른 사람들이 사용하거나 개선하기위한 예입니다. 이 솔루션을 원하는 사람들에게 이것을 공유하겠다고 생각했습니다.

코드를 잘라서 그대로 작동하지 않을 수 있습니다.


'저장하고 싶었던 변경 사항이 있습니다.' 나를 위해 일하지 않았다. 메시지를 'warning_message'라는 변수에 저장해야했고 warning_message를 반환했습니다. 그런 다음에 만 나를 위해 일했습니다!.
Suganya

IE, Chrome, Firefox에서 테스트 했습니까?
Kiquenet

9

1) 언로드가 아닌 onbeforeunload를 사용하십시오.

2) 중요한 것은 return 문을 실행하지 않는 것입니다. 나는 이것이 당신의 핸들러에서 돌아 오는 것을 피하기 위해 의미하지는 않습니다. 모든 것을 반환하지만 함수의 끝에 도달하고 return 문을 실행하지 않아야합니다. 이러한 조건에서는 내장 표준 대화 상자가 나타나지 않습니다.

3) onbeforeunload를 사용하는 경우 unbeforeunload 처리기에서 ajax 호출을 실행하여 서버를 정리할 수 있지만 동기식이어야하며 onbeforeunload 처리기에서 응답을 기다려 처리해야합니다 (여전히 존중 상기 조건 (2)). 나는 이것을하고 잘 작동합니다. 동기식 아약스 호출을 수행하면 응답이 다시 올 때까지 모든 것이 유지됩니다. 비동기 응답을 수행하는 경우 서버의 응답에 신경 쓰지 않는다고 생각하면 페이지 언로드가 계속되고이 프로세스에서 실행중인 원격 스크립트를 포함하여이 프로세스에서 ajax 호출이 중단됩니다.


FYI 누구든지 이것을 읽고 ^ 크롬은 unbeforeunload에서 동기 AJAX 호출을 더 이상 사용하지 않습니다
morganwebdev

4

재치보십시오 return;이 나를 위해 대부분의 브라우저를하고있다 .. 대신 메시지. (이것은 실제로 대화의 선물을 막습니다)

window.onbeforeunload = function(evt) {            
        //Your Extra Code
        return;
}

3
는 null은 개방에서 대화 방지 할 수 있습니다
브렛 웨버에게

1
null을 반환해도 대화 상자가 열리지 않습니다. Chrome에서 시도했지만 사실이 아닙니다.
Ray

2
IE에서도 Ray의 의견을 확인할 수 있습니다. 돌아 가면 null"null"이라는 텍스트가있는 대화 상자가 열립니다. 그러나 return void(0);대화 상자가 열리지 않습니다.
MCattle

1
beforeunload 함수에 return 문을 넣지 않으면 대화 상자가 열리지 않습니다.
OuuGiii


3

onunload 기능은 사용자가 페이지를 떠날 때만 호출되므로 사용자가 누른 버튼 (확인 또는 취소)을 감지 할 수 있습니다. 이 기능에서는 DOM이 축소되기 때문에 가능성이 제한됩니다. 자바 스크립트를 실행할 수 있지만 ajax POST는 아무 것도하지 않으므로 자동 로그 아웃에이 방법을 사용할 수 없습니다. 그러나 그에 대한 해결책이 있습니다. onunload 기능에서 window.open ( 'logout.php')이 실행되었으므로 사용자는 새 창 열기로 로그 아웃합니다.

function onunload = (){
    window.open('logout.php');
}

이 코드는 사용자가 페이지를 떠나거나 활성 창을 닫고 'logout.php'로 로그 아웃 할 때 호출됩니다. 로그 아웃 PHP가 코드로 구성되면 새 창이 즉시 닫힙니다.

window.close();

beforeunload 및 unload 함수에서 동기 포스트를 사용할 수 있습니다. 특히 서버에서 데이터를 다시 받아야하는 경우. 해당 블록 내의 비동기 코드는 페이지가 언로드 될 때까지 완료되지 않을 수 있습니다.
jemiloii 2016

3

나는 같은 문제에 직면하여 내 메시지와 함께 자체 대화 상자를 얻을 수 있었지만, 내가 직면 한 문제는 다음과 같습니다. 1) 모든 탐색에서 메시지를주는 것이 었습니다. 클릭 만하면됩니다. 2) 내 확인 메시지와 함께 사용자가 취소를 선택하면 여전히 브라우저의 기본 대화 상자가 표시됩니다.

다음은 내가 찾은 솔루션 코드이며 마스터 페이지에 작성했습니다.

function closeMe(evt) {
    if (typeof evt == 'undefined') {
        evt = window.event; }
    if (evt && evt.clientX >= (window.event.screenX - 150) &&
        evt.clientY >= -150 && evt.clientY <= 0) {
        return "Do you want to log out of your current session?";
    }
}
window.onbeforeunload = closeMe;


1

"bind"명령 "one"의 특수 버전을 사용하는 것은 어떻습니까? 이벤트 핸들러가 처음 실행되면 이벤트 핸들러로 자동 제거됩니다.

$(window).one("beforeunload", BeforeUnload);

.on

2
@SergiuMindras 아니오, 그것은 .one()-이벤트 리스너를 연결하여 한 번만 발생하는 이벤트를 수신하는 것입니다. api.jquery.com/one
Sean Kendle

0

각도 9 접근 방식 :

constructor() {
    window.addEventListener('beforeunload', (event: BeforeUnloadEvent) => {
     if (this.generatedBarcodeIndex) {
      event.preventDefault(); // for Firefox
      event.returnValue = ''; // for Chrome
      return '';
     }
     return false;
    });
   }

브라우저는 사용자 정의 메시지를 지원하고 제거합니다.

  • Chrome에서 51 분 내에 맞춤 메시지에 대한 지원이 제거되었습니다.
  • Opera는 38 분 내에 커스텀 메시지에 대한 지원을 제거했습니다.
  • Firefox는 44.0 분 후에 커스텀 메시지에 대한 지원을 제거했습니다.
  • Safari에서 9.1 분 내에 사용자 정의 메시지에 대한 지원이 제거되었습니다.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.