onbeforeunload를 프롬프 한 후 사용자가 머무르는 지 여부를 감지합니다

StackOverflow https://stackoverflow.com/questions/821481

  •  03-07-2019
  •  | 
  •  

문제

내가 작업중 인 웹 앱에서 나는 onbeforeunload를 캡처하여 사용자에게 그가 진짜 종료하고 싶어.

이제 그가 머물기로 결심한다면 내가하고 싶은 일이 많이 있습니다. 내가 알아 내려고하는 것은 그가 실제로 머물기로 선택했다는 것입니다.

물론 "x"초로 설정 타임 아웃을 선언 할 수 있으며, 해고되면 사용자가 여전히 존재한다는 것을 의미합니다 (우리는 언로드되지 않았기 때문에). 문제는 사용자가 머무를지 여부를 결정하는 데 시간이 걸릴 수 있다는 것입니다.

먼저 대화 상자가 표시되는 동안 Settimeout 통화가 시작되지 않기를 바랐으므로 짧은 시간 동안 타임 아웃을 설정할 수 있었고 사용자가 머무르기로 선택한 경우에만 해고되었습니다. 그러나 타임 아웃 하다 대화 상자가 표시되는 동안 발사하므로 작동하지 않습니다.

내가 시도한 또 다른 아이디어는 창/문서에서 무스 마모를 캡처하는 것입니다. 대화 상자가 표시되는 동안, Mousemoves는 실제로 내 케이스에 실제로 적용되는 이상한 예외를 제외하고는 실제로 발사되지 않으므로 작동하지 않습니다.

누구 든지이 작업을 수행하는 다른 방법을 생각할 수 있습니까?

감사!


(궁금한 경우, MouseMove를 캡처하는 이유는 작동하지 않는 이유는 내 페이지에 다른 도메인에서 사이트를 포함하는 iframe이 있기 때문입니다. 페이지를 내릴 때 초점이 iframe 내에있는 동안 대화 상자는 마우스가 Iframe 내부에서 외부로 이동할 때 (적어도 Firefox에서) MouseMove 이벤트가 한 번 발사됩니다. 아마도 버그 일 것입니다. 그러나 여전히 우리의 경우에 일어날 가능성이 높습니다. 이 방법을 사용할 수 없습니다).

도움이 되었습니까?

해결책

내가 한 일은 내 문서의 클릭 이벤트에 연결하는 것이었고, 클릭을 받으면 사용자가 머물렀다 고 생각했습니다.

그것은 좋은 해결책이 아닙니다. 대부분의 경우 (당신이 diggbar 인 경우) 많은 잘못된 부정적인 것을 가질 것입니다 (사람들은 머물러 있고 결코 알지 못할 것입니다). 그러나 우리의 경우 사람들이 상호 작용하기 때문에 완벽하게 이해되었습니다. 프레임 사이트뿐만 아니라 우리 사이트와 크게.

내 코드는이 작업을 수행합니다 ...

function OnBeforeUnload() {
    Event.observe(document, "click", UserStayed);
    if (IConsiderTheIFrameMightBeTryingToPopOut) {
        return "The site is trying to escape. Do you want to stay?";
    }
}

function UserStayed() {
Event.stopObserving(document, "click", UserStayed);
    // New we know the user is still with us for sure.
}

다른 팁

나는 지난 며칠 동안이 질문을 온라인으로 연구 해 왔으며, 대답은 항상 "아니오"입니다. 사용자가 머물거나 떠났다고 말할 수는 없습니다 (사용자가 떠나면 앱이 작동하지 않는다는 사실을 제외하고는 ). 나는 "아니오"대답을 싫어합니다. 나는 다음 유틸리티를 생각해 냈습니다.

var OnBeforeUnload = (function(){
    var
    FDUM = new Function,
    AFFIRM = function(){ return true; };

    var _reg = function(msg,opts){
        opts = opts || {};
        var
            pid = null,
            pre = typeof opts.prefire == 'function' ? opts.prefire : FDUM,
            callback = typeof opts.callback == 'function' ? opts.callback : FDUM,
            condition = typeof opts.condition == 'function' ? opts.condition : AFFIRM;

        window.onbeforeunload = function(){
            return condition() ? (pre(),setTimeout(function(){ pid = setTimeout(callback,20); },1),msg) : void 0; 
        }

        window.onunload = function(){ clearTimeout(pid); };

    }

    var _unreg = function(){ window.onbeforeunload = null;  }

    return {
        register : _reg,
        unregister : _unreg
    };

})();

따라서, 다음과 같은 전화

OnBeforeUnload.register('Hello!',{ 
    condition:function_that_returns_true_to_fire_event_false_to_ignore,
    prefire:function_to_call_on_page_exit_attempt, 
    callback:function_to_call_if_user_stays
});

핸들러 내에서 조건이 호출되어 활성화 여부를 확인합니다. 그렇다면 팝업이 사용자에게 표시되기 전에 사전 파이어가 실행되며 (비디오를 일시 중지 할 수 있음) 콜백은 사용자가 유지되는 경우에만 발생합니다.

내 논리는 이벤트 핸들러 본문에서 설정 타임 아웃을 시작하는 것이 었습니다. 사용자가 버튼 중 하나를 누르기 전까지는 설정 타임 아웃이 실행되지 않습니다. 그들이 한 후에, 그것은 즉시 발사됩니다. 이 경우 설정 타임 아웃은 콜백을 호출하지 않고 20ms의 지연으로 콜백의 다른 시간 초과를 실행하는 프록시 함수입니다. 사용자가 페이지에 머무르면 콜백이 실행됩니다. 그렇지 않은 경우, 다른 핸들러가 OnUnload에 부착되어 콜백을 호출 할 시간 초과를 지우므로 콜백이 호출되지 않도록합니다. 나는 Firefox, IE 및 Chrome에서 확인할 기회 만 있었지만 지금까지 딸꾹질없이 세 가지 모두에서 작동했습니다.

나는 이것이이 질문에 보편적으로 주어진 특허 "No"에 의해 사람들이 좌절하는 것처럼 사람들을 도울 수 있기를 바랍니다. 이 코드는 완벽하지는 않지만 올바른 추적에 있다고 생각합니다.

이것은 이러한 유형의 질문에 대한 최고 히트이며, 8 년 전의 특정 사례는 Iframe에 있었기 때문에이 솔루션을 사용할 수 없다는 것을 알고 있지만 미래의 이민자들은 아마도 아래의 답변에 의해 더 도움이 될 것입니다. 위의 것 :

그들이 바디 이벤트 청취자와 함께 머물렀는지 쉽게 알 수 있습니다. MouseMove와 KeyDown이 충분해야한다고 생각합니다.

그들이 떠난 지 알기 위해서는 서버 측면이 필요합니다.

대체로, 그것은 이런 식으로 보일 것입니다 (당신은 서버에 대한 Ajax 호출을 직접 채워야합니다) :

window.addEventListener("beforeunload", function(event){
    //tell your server they are attempting to leave
    var tryLeaveID = serverLogAttempToLeave();

    //an element with giant letters and warning text, because you can no longer set text on the alert box
    var unsavedWarning = document.getElementById("unsavedChangesWarning");
    unsavedWarning.style.display = "block";

    var onStay = function() {
        //if they stay, tell your server so
        serverRevokeAttemptToLeave(tryLeaveID);
        unsavedWarning.style.display = "none";
        document.body.removeEventListener("mousemove", onStay);
        document.body.removeEventListener("keydown", onStay);
    }

    document.body.addEventListener("mousemove", onStay);
    document.body.addEventListener("keydown", onStay);


    var dialogText =  "undisplayed text";
    event.returnValue = dialogText;
    return dialogText;
});

서버 측에서는 추악한 타이머를 사용해야합니다. 떠나려는 시도를 스택하고, 체류에 요청 된대로 또는 1 분 정도 후에 확인 된 휴가로 제거하십시오. 사용자가 남은 시간을 아는 것이 몇 분보다 더 민감한 경우를 상상할 수 없지만, 하나가 있다면, 그것에 대해 생각하고 싶기 때문에 의견을 제시하십시오.

STACKOVERFLOW가하는 메소드를 사용하여 선택할 수있는 팝업 상자를 얻을 수있는 방법을 사용하지 않겠습니까?

이 페이지에서 멀리 탐색 하시겠습니까?

게시물을 작성하거나 편집하기 시작했습니다.

계속하려면 확인을 누르거나 현재 페이지에 남아 있으려면 취소

그렇다면 그들이 얼마나 오래 걸리는지는 중요하지 않습니다. 하나의 버튼을 클릭하면 떠납니다. 그들이 다른 것을 클릭하면, 그들은 머물러 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top