programing

브라우저 또는 탭 닫기 감지

goodsources 2022. 9. 12. 11:55
반응형

브라우저 또는 탭 닫기 감지

브라우저 또는 브라우저 탭이 닫혔는지 여부를 검출하는 크로스 브라우저 JavaScript/jQuery 코드가 있습니까?링크가 클릭되어 있지 않습니까?

제 말이 맞다면 탭/창이 언제 닫히는지 알고 싶을 겁니다.은 AFAIK 중 하나를 onunload ★★★★★★★★★★★★★★★★★」onbeforeunload벤트입입니니다

유감스럽게도(또는 다행스럽게도?) 이러한 이벤트는 링크를 통해 사이트를 떠나거나 브라우저의 뒤로 버튼을 클릭할 때도 발생합니다. 이게 수 최선의 입니다. 수 것 순수하게는 찾을 수 없다고 생각합니다.close자바스크립트제가 틀렸다면 정정해 주세요.

MDN 매뉴얼에서

어떤 이유로 웹킷 기반 브라우저는 대화상자의 사양을 따르지 않습니다.거의 크로스워킹의 예는 다음 예와 비슷합니다.

window.addEventListener("beforeunload", function (e) {
  var confirmationMessage = "\o/";

  (e || window.event).returnValue = confirmationMessage; //Gecko + IE
  return confirmationMessage;                            //Webkit, Safari, Chrome
});

이 예에서는 모든 브라우저를 처리합니다.

심플한 솔루션

window.onbeforeunload = function () {
    return "Do you really want to close?";
};
<body onbeforeunload="ConfirmClose()" onunload="HandleOnClose()">

var myclose = false;

function ConfirmClose()
{
    if (event.clientY < 0)
    {
        event.returnValue = 'You have closed the browser. Do you want to logout from your application?';
        setTimeout('myclose=false',10);
        myclose=true;
    }
}

function HandleOnClose()
{
    if (myclose==true) 
    {
        //the url of your logout page which invalidate session on logout 
        location.replace('/contextpath/j_spring_security_logout') ;
    }   
}

//1개의 탭만으로 탭 또는 브라우저를 닫는 경우 IE7에서 동작합니다.

에는 " " 를 사용할 수 .sessionStorage브라우저 탭이 닫힐 때까지 데이터를 로컬로 저장합니다.

sessionStorageobject는 한 세션의 데이터만 저장합니다(브라우저 탭이 닫히면 데이터가 삭제됩니다).(W3 학교)

이것은 제 펜입니다.

<div id="Notice">
    <span title="remove this until browser tab is closed"><u>dismiss</u>.</span>
</div>
<script>
    $("#Notice").click(function() {
     //set sessionStorage on click
        sessionStorage.setItem("dismissNotice", "Hello");
        $("#Notice").remove();
    });
    if (sessionStorage.getItem("dismissNotice"))
    //When sessionStorage is set Do stuff...
        $("#Notice").remove();
</script>

브라우저나 탭이 닫힐 때 사용자를 자동으로 로그아웃해야 했지만 사용자가 다른 링크로 이동할 때는 로그아웃하지 않아야 했습니다.그 때 확인 프롬프트가 뜨는 것도 원치 않았습니다.특히 IE와 Edge에 대해 한동안 고민한 후, 이 답변에 따라 IE 11, Edge, Chrome 및 Firefox에 대한 작업을 확인했습니다.

합니다.beforeunload이벤트 핸들러입니다.IE 와 엣지가 정상적으로 동작하려면 , ajax 콜이 동기 할 필요가 있습니다.도 사용해야 .return;확인 대화상자가 다음과 같이 표시되지 않도록 하려면:

    window.addEventListener("beforeunload", function (e) {        
      $.ajax({
          type: "POST",
          url: startTimerUrl,
          async: false           
      });
      return;
    });

하면, 「」가 됩니다.cancelLogoutfalse로 플래그를 설정합니다.사용자가 페이지를 갱신하거나 다른 내부 링크로 이동하면cancelLogout서버의 플래그가 true로 설정되어 있습니다.타이머 이벤트가 경과하면 이 이벤트는cancelLogout플래그를 클릭하여 로그아웃이벤트가 취소되었는지 여부를 확인합니다.타이머가 취소되면 타이머가 정지됩니다. 있는 는, 「」를 참조해 .cancelLogout플래그는 false로 유지되며 이벤트 핸들러는 사용자를 로그아웃합니다.

사용하고 ASP를 사용하다 MVC 5 am canceling overrided NET MVC 5 입니다.Controller.OnActionExecuted()★★★★★★ 。

모든 브라우저에서 작동하는 방법을 찾았어요.

다음 버전에서 테스트 완료:Firefox 57, Internet Explorer 11, Edge 41, 최신 Chrome 중 하나(내 버전은 표시되지 않음)

주의: onbefore unload는 가능한 한 페이지를 벗어나면 실행됩니다(새로고침, 브라우저 닫기, 리디렉션, 링크, 전송 등).브라우저 종료 시에만 실행할 경우 이벤트 핸들러를 바인딩하기만 하면 됩니다.

  $(document).ready(function(){         

        var validNavigation = false;

        // Attach the event keypress to exclude the F5 refresh (includes normal refresh)
        $(document).bind('keypress', function(e) {
            if (e.keyCode == 116){
                validNavigation = true;
            }
        });

        // Attach the event click for all links in the page
        $("a").bind("click", function() {
            validNavigation = true;
        });

        // Attach the event submit for all forms in the page
        $("form").bind("submit", function() {
          validNavigation = true;
        });

        // Attach the event click for all inputs in the page
        $("input[type=submit]").bind("click", function() {
          validNavigation = true;
        }); 

        window.onbeforeunload = function() {                
            if (!validNavigation) {     
                // ------->  code comes here
            }
        };

  });

도 없지만 이 있다.window.closed이는 본 기술 시점부터 모든 주요 브라우저에서 지원됩니다.따라서 꼭 알아야 할 경우 해당 속성을 확인하기 위해 창을 폴링할 수 있습니다.

if(myWindow.closed){do things}

주의: 일반적으로 폴링하는 것은 최선의 해결책이 아닙니다.window.onbeforeunload가능하면 이벤트를 사용해야 합니다.단, 주의할 점은 다른 곳으로 이동해도 이벤트가 발생한다는 것입니다.

죄송합니다. 기존 답변 중 하나에 코멘트를 추가하지 못했습니다만, 일종의 경고 대화상자를 구현하고자 하는 경우 이벤트 핸들러 함수에 인수 이벤트가 있음을 알려드리고자 합니다.이 경우 event.preventDefault()를 호출하여 자동으로 페이지 이탈을 허용하지 않도록 한 후 자체 대화상자를 발행할 수 있습니다.표준적인 추악하고 안전하지 않은 경보를 사용하는 것보다 이 방법이 더 낫다고 생각합니다.저는 개인적으로 kendoWindow 오브젝트(telerik의 Kendo UI, kendoGrid 및 kendoEditor를 제외하고 거의 완전히 오픈 소스)를 기반으로 한 일련의 대화 상자를 구현했습니다.jQuery UI에서 대화 상자를 사용할 수도 있습니다.다만, 이러한 것은 비동기이며, 모든 버튼의 클릭 이벤트에 핸들러를 바인드 할 필요가 있습니다만, 이 모든 것을 실장하는 것은 매우 간단합니다.

다만, 리얼 클로즈 이벤트가 없는 것은 매우 심각하다는 것은 인정합니다.예를 들어, 리얼 클로즈 이벤트가 발생했을 경우에만 백엔드에서 세션 상태를 리셋하는 것은 문제가 됩니다.

$(window).unload( function () { alert("Bye now!"); } );

아직 아무도 이에 대해 언급하지 않았기 때문에(8년 이상 경과)WebSocket은 닫힌 탭을 감지하는 또 다른 효과적인 방법입니다.탭이 열려 있고 호스트를 가리키고 있는 한 클라이언트는 호스트에 대한 활성 WebSocket 연결을 유지할 수 있습니다.

주의: 이 솔루션은 WebSocket이 이미 진행 중인 작업에서 상당한 오버헤드를 필요로 하지 않는 경우에만 실제로 사용할 수 있습니다.

적절한 타임아웃 시간(예를 들어 2분) 내에 서버 측은 WebSocket이 절단된 후 클라이언트가 사라졌다고 판단할 수 있으며 업로드된 임시 파일 삭제 등 원하는 작업을 수행할 수 있습니다(제 특수한 사용 예에서는 WebSocket conn 3초 후에 로컬 호스트 애플리케이션 서버를 종료하는 것이 목표였습니다).모든 CGI/Fast CGI 액티비티가 종료됩니다.다른 킵얼라이브 접속은 영향을 받지 않습니다.)

언로드 시 이벤트핸들러가 비콘과 올바르게 동작하는 데 문제가 있었습니다(이 답변에서 권장하는 바와 같습니다).탭을 닫아도 비콘이 트리거되지 않고 탭이 열려 문제가 발생할 수 있는 방식으로 트리거되지 않았습니다.Web Socket을 사용하면, 탭이 닫히는 것과 거의 동시에 접속이 종료되어 애플리케이션내의 페이지를 전환하면, 지연창내에 새로운 Web Socket 접속이 간단하게 열리기 때문에, 보다 깔끔하게 Web Socket에 의해서 문제가 해결되었습니다.

onunloadChrome의 답입니다.caniuse에 따르면 크로스브라우저는그러나 모든 브라우저가 동일한 반응을 보이는 것은 아닙니다.

window.onunload = function(){
    alert("The window is closing now!");
}

developer.mozilla.org

이러한 이벤트는 창이 콘텐츠 및 리소스를 언로드할 때 발생합니다.

Chrome의 경우:

onunload는 페이지 닫기 에만 실행됩니다.페이지 새로 고침 및 다른 페이지로 이동할 때도 실행되지 않습니다.

Firefox v86.0의 경우:

그것은 전혀 실행되지 않을 것이다.페이지 새로 고침, 이동, 브라우저 탭 닫기, 브라우저 닫기, 아무것도 없습니다.

window.onbeforeunload = function() {
  console.log('event');
  return false; //here also can be string, that will be shown to the user
}
window.addEventListener("beforeunload", function (e) {
 var confirmationMessage = "tab close";

 (e || window.event).returnValue = confirmationMessage;     //Gecko + IE
 sendkeylog(confirmationMessage);
 return confirmationMessage;                                //Webkit, Safari, Chrome etc.
}); 
//Detect Browser or Tab Close Events
$(window).on('beforeunload',function(e) {
  e = e || window.event;
  var localStorageTime = localStorage.getItem('storagetime')
  if(localStorageTime!=null && localStorageTime!=undefined){
    var currentTime = new Date().getTime(),
        timeDifference = currentTime - localStorageTime;

    if(timeDifference<25){//Browser Closed
       localStorage.removeItem('storagetime');
    }else{//Browser Tab Closed
       localStorage.setItem('storagetime',new Date().getTime());
    }

  }else{
    localStorage.setItem('storagetime',new Date().getTime());
  }
});

JSFiddle 링크

안녕하세요, 저는 브라우저의 로컬 스토리지와 타임스탬프를 사용하여 '브라우저 검출 및 탭 닫기 이벤트' 클릭을 할 수 있었습니다.여러분 모두가 이 솔루션을 사용하여 문제를 해결하기를 바랍니다.

초기 조사 결과 브라우저를 닫으면 브라우저가 모든 탭을 하나씩 닫아서 브라우저를 완전히 닫는다는 것을 알게 되었습니다.따라서 탭을 닫을 때까지의 시간 지연은 거의 없습니다.그래서 저는 이 시간 지연을 주요 검증 포인트로 삼고 브라우저와 탭 닫기 이벤트 검출을 달성할 수 있었습니다.

Chrome 브라우저 버전76.0.3809.132로 테스트해 보니 동작하고 있는 것을 알 수 있었습니다.

:) 제 답변이 도움이 될 것 같으면 투표해주세요.

위의 모든 솔루션을 시도해 보았지만, 어느 것도 나에게 효과가 없었습니다.특히 제 프로젝트에는 팝업창에 '닫기' 버튼이 있는 Telerik 컴포넌트가 있어서 '언로드 전' 이벤트를 호출하고 있기 때문입니다.또, 페이지에 Telerik 그리드가 있으면 버튼 셀렉터가 제대로 작동하지 않기 때문에(그리드 내부의 버튼) 위의 어떤 제안도 사용할 수 없었습니다.마침내 이것이 나에게 효과가 있는 해결책이다._Layout.cshtml 본문 태그에 onUnload 이벤트를 추가하였습니다.다음과 같은 경우:

<body onUnload="LogOff()">

그런 다음 LogOff 함수를 추가하여 Asp에 내장된 메서드인 Account/LogOff로 리디렉션합니다.넷 MVC이제 브라우저 또는 탭을 닫으면 LogOff 메서드로 리다이렉트되며 사용자는 반환 시 로그인해야 합니다.Chrome과 Firefox 모두 테스트했습니다.그리고 효과가 있다!

  function LogOff() {
        $.ajax({
            url: "/Account/LogOff",
            success: function (result) {

                                        }
               });
       }
window.onbeforeunload = function ()
{       

    if (isProcess > 0) 
    {
        return true;       
    }   

    else
    { 
        //do something      
    }
}; 

이 기능은 브라우저에서 프로세스 중에 창을 닫거나 페이지를 새로 고치면 확인 대화 상자를 표시합니다.이 기능은 모든 브라우저에서 작동합니다.ajax 프로세스에서 isProcess var를 설정해야 합니다.

다음과 같은 'unload' 이벤트에서 이벤트 핸들러에서 window.closed를 사용하여 확인할 수 있지만 타임아웃 사용이 필요합니다(따라서 smth 지연 또는 창 닫힘 방지 시 결과를 보장할 수 없습니다).

JSFiddle의 예(lates Safari, FF, Chrome, Edge 및 IE11에서 테스트)

var win = window.open('', '', 'width=200,height=50,left=200,top=50');
win.document.write(`<html>
   <head><title>CHILD WINDOW/TAB</title></head>
   <body><h2>CHILD WINDOW/TAB</h2></body>
</html>`);
win.addEventListener('load',() => {
    document.querySelector('.status').innerHTML += '<p>Child was loaded!</p>';
});
win.addEventListener('unload',() => {
    document.querySelector('.status').innerHTML += '<p>Child was unloaded!</p>';
    setTimeout(()=>{
        document.querySelector('.status').innerHTML +=  getChildWindowStatus();
    },1000);
});
win.document.close()
document.querySelector('.check-child-window').onclick = ()=> {
    alert(getChildWindowStatus());
}
function getChildWindowStatus() {
  if (win.closed) { 
      return 'Child window has been closed!';
  } else {
      return 'Child window has not been closed!';
  }
}

앱을 종료할 때 사용자를 더 잘 태킹할 수 있도록 브라우저가 업데이트되었습니다.'가시성 변경' 이벤트를 통해 페이지가 다른 탭에서 숨겨지거나 닫혀 있을 때 고정할 수 있습니다.문서 가시성 상태를 추적할 수 있습니다.속성 document.visibilityState는 현재 상태를 반환합니다.로그인 및 로그아웃을 추적해야 하지만 목표에 더 가깝습니다.

새로운 브라우저에서는 지원되지만 safari(알고 있는 바와 같이)는 표준에 준거하지 않습니다.'페이지쇼'와 '페이지숨김'을 사용하여 사파리에서 작업할 수 있습니다.

탭이 닫히고 응답이 없을 때 서버에 단방향 요청을 보내기 위해 sendBeacon과 같은 새로운 API를 사용할 수도 있습니다.

이것을 추적하기 위해 사용하는 클래스의 퀵 포트를 만듭니다.프레임워크에서 몇 가지 콜을 삭제해야 했기 때문에 버그가 발생할 수 있지만 이것으로 시작할 수 있을 것입니다.

export class UserLoginStatus
{
    /**
     * This will add the events and sign the user in.
     */
    constructor()
    {
        this.addEvents();
        this.signIn();
    }

    /**
     * This will check if the browser is safari. 
     * 
     * @returns {bool}
     */
    isSafari()
    {
        if(navigator && /Safari/.test(navigator.userAgent) && /Chrome/.test(navigator.userAgent))
        {
            return (/Google Inc/.test(navigator.vendor) === false);
        }
        return false;
    }

    /**
     * This will setup the events array by browser.
     * 
     * @returns {array}
     */
    setupEvents()
    {
        let events = [
            ['visibilitychange', document, () =>
            {
                if (document.visibilityState === 'visible')
                {
                    this.signIn();
                    return;
                }

                this.signOut();
            }]
        ];

        // we need to setup events for safari
        if(this.isSafari())
        {
            events.push(['pageshow', window, (e) =>
            {
                if(e.persisted === false)
                {
                    this.signIn();
                }
            }]);

            events.push(['pagehide', window, (e) =>
            {
                if(e.persisted === false)
                {
                    this.signOut();
                }
            }]);
        }

        return events;
    }

    /**
     * This will add the events.
     */
    addEvents()
    {
        let events = this.setupEvents();
        if(!events || events.length < 1)
        {
            return;
        }

        for(var i = 0, length = events.length; i < length; i++)
        {
            var event = events[i];
            if(!event)
            {
                continue;
            }

            event[1].addEventListener(event[0], event[3]);
        }
    }

    /**
     * 
     * @param {string} url 
     * @param {string} params 
     */
    async fetch(url, params)
    {
        await fetch(url, 
        {
            method: 'POST',
            body: JSON.stringify(params)
        });
    }

    /**
     * This will sign in the user.
     */
    signIn()
    {
        // user is the app
        const url = '/auth/login';
        let params = 'userId=' + data.userId;

        this.fetch(url, params);
    }

    /**
     * This will sign out the user.
     */
    signOut()
    {
        // user is leaving the app

        const url = '/auth/logout';
        let params = 'userId=' + data.userId;

        if(!('sendBeacon' in window.navigator))
        {
            // normal ajax request here
            this.fetch(url, params);
            return;
        }

        // use a beacon for a more modern request the does not return a response
        navigator.sendBeacon(url, new URLSearchParams(params));
    }
}

일부 데이터가 저장되지 않은 경우 사용자에게 경고하는 데 사용할 수 있습니다.이 방법은 탭이 닫히거나 브라우저가 닫히거나 웹 페이지를 새로 고칠 때 작동합니다.

사용자가 웹 페이지와 상호 작용하지 않는 한 Google Chrome은 상호 작용하지 않습니다. 이는 악의적인 웹 사이트 때문입니다....이 경우 텍스트 영역을 클릭하지 않으면 팝업이 표시되지 않습니다.

<!DOCTYPE html>
<html>
<head>
</head>
<body>
    <form>
        <textarea placeholder = "Write...."></textarea>
    </form>
    <script type="text/javascript">
        window.addEventListener('beforeunload', function (e) {
            e.returnValue = '';
        });
    </script>
</body>
</html>

저의 접근방식은 다음과 같습니다.

  1. onpopstate를 사용하여 URL에서 변경 내용을 수신하고 1로 sessionStorage 변수를 설정합니다.
  2. 페이지 로드를 수신하고 해당 sessionStorage 변수를 0으로 설정합니다.
  3. 언로드 전에 변수가 0인지 확인합니다.이 경우 사용자가 url을 변경하지 않고 닫는다는 것을 의미합니다.

이것은 아직 우회적인 방법이지만, 나에게는 이해가 간다.

@jandy가 언급했듯이 창이 닫히는 것을 감지하기 위한 적절한 Javascript 코드가 없습니다.나는 @Syno가 제안한 것부터 시작했다.

나는 그런 상황을 겪어봤고 당신이 이 단계를 따르면, 당신은 그것을 발견할 수 있을 것입니다.
Chrome 67+와 Firefox 61+에서 테스트했습니다.

var wrapper = function () { //ignore this

var closing_window = false;
$(window).on('focus', function () {
    closing_window = false; 
   //if the user interacts with the window, then the window is not being 
   //closed
});

$(window).on('blur', function () {

    closing_window = true;
    if (!document.hidden) { //when the window is being minimized
        closing_window = false;
    }
    $(window).on('resize', function (e) { //when the window is being maximized
        closing_window = false;
    });
    $(window).off('resize'); //avoid multiple listening
});

$('html').on('mouseleave', function () {
    closing_window = true; 
    //if the user is leaving html, we have more reasons to believe that he's 
    //leaving or thinking about closing the window
});

$('html').on('mouseenter', function () {
    closing_window = false; 
    //if the user's mouse its on the page, it means you don't need to logout 
    //them, didn't it?
});

$(document).on('keydown', function (e) {

    if (e.keyCode == 91 || e.keyCode == 18) {
        closing_window = false; //shortcuts for ALT+TAB and Window key
    }

    if (e.keyCode == 116 || (e.ctrlKey && e.keyCode == 82)) {
        closing_window = false; //shortcuts for F5 and CTRL+F5 and CTRL+R
    }
});

// Prevent logout when clicking in a hiperlink
$(document).on("click", "a", function () {
    closing_window = false;
});

// Prevent logout when clicking in a button (if these buttons rediret to some page)
$(document).on("click", "button", function () {
    closing_window = false;

});
// Prevent logout when submiting
$(document).on("submit", "form", function () {
    closing_window = false;
});
// Prevent logout when submiting
$(document).on("click", "input[type=submit]", function () {
    closing_window = false;
});

var toDoWhenClosing = function() {

    //write a code here likes a user logout, example: 
    //$.ajax({
    //    url: '/MyController/MyLogOutAction',
    //    async: false,
    //    data: {

    //    },
    //    error: function () {
    //    },
    //    success: function (data) {
    //    },
    //});
};


window.onbeforeunload = function () {
    if (closing_window) {
        toDoWhenClosing();
    }
};

};

이거 먹어봐, 분명 잘 될 거야.

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type='text/javascript'>
    $(function() {

        try{
            opera.setOverrideHistoryNavigationMode('compatible');
            history.navigationMode = 'compatible';
        }catch(e){}

        function ReturnMessage()
        {
            return "wait";
        }

        function UnBindWindow()
        {
            $(window).unbind('beforeunload', ReturnMessage);
        }

        $(window).bind('beforeunload',ReturnMessage );
    });
</script>

이거 먹어봐.동작합니다.jquery 언로드 메서드는 더 이상 사용되지 않습니다.

window.onbeforeunload = function(event) {
    event.returnValue = "Write something clever here..";
};

언급URL : https://stackoverflow.com/questions/3888902/detect-browser-or-tab-closing

반응형