Programming

브라우저 뒤로 버튼 이벤트를 감지하는 방법-크로스 브라우저

procodes 2020. 5. 18. 21:13
반응형

브라우저 뒤로 버튼 이벤트를 감지하는 방법-크로스 브라우저


사용자가 브라우저에서 뒤로 버튼을 눌렀는지 여부를 어떻게 정확하게 감지합니까?

#URL시스템을 사용하여 단일 페이지 웹 응용 프로그램에서 인 페이지 뒤로 단추를 어떻게 사용 합니까?

왜 지구상에서 브라우저 백 버튼이 자체 이벤트를 발생시키지 않습니까!?


(참고 : Sharky의 피드백에 따라 백 스페이스를 감지하는 코드를 포함 시켰습니다)

그래서 나는 SO에서 이러한 질문을 자주 보았으며 최근에는 뒤로 버튼 기능을 직접 제어하는 ​​문제가 발생했습니다. 내 응용 프로그램 (싱글 페이지가있는 단일 페이지)에 가장 적합한 솔루션을 며칠간 검색 한 후에 뒤로 버튼을 감지하기위한 간단한 브라우저 간 라이브러리가없는 시스템이 나타났습니다.

대부분의 사람들은 다음을 사용하는 것이 좋습니다.

window.onhashchange = function() {
 //blah blah blah
}

그러나이 함수는 사용자가 위치 해시를 변경하는 인 페이지 요소를 사용할 때도 호출됩니다. 사용자가 클릭하고 페이지가 앞뒤로 이동할 때 최상의 사용자 환경이 아닙니다.

내 시스템에 대한 일반적인 개요를 제공하기 위해 사용자가 인터페이스를 이동할 때 이전 해시로 배열을 채우고 있습니다. 다음과 같이 보입니다 :

function updateHistory(curr) {
    window.location.lasthash.push(window.location.hash);
    window.location.hash = curr;
}

꽤 직설적 인. 브라우저 간 지원 및 구형 브라우저 지원을 위해이 작업을 수행합니다. 새 해시를 함수에 전달하면 해시가 저장되어 해시가 변경됩니다 (브라우저 기록에 저장 됨).

또한 lasthash배열을 사용하여 페이지간에 사용자를 이동하는 인 페이지 뒤로 버튼을 사용합니다 . 다음과 같이 보입니다 :

function goBack() {
    window.location.hash = window.location.lasthash[window.location.lasthash.length-1];
    //blah blah blah
    window.location.lasthash.pop();
}

따라서 이것은 사용자를 마지막 해시로 다시 이동시키고 배열에서 마지막 해시를 제거합니다 (지금은 앞으로 버튼이 없습니다).

그래서. 사용자가 인 페이지 뒤로 버튼 또는 브라우저 버튼을 사용했는지 여부를 어떻게 감지합니까?

처음에는을 보았지만 window.onbeforeunload아무 소용이 없었습니다. 사용자가 페이지를 변경하려는 경우에만 호출됩니다. 해시 탐색을 사용하는 단일 페이지 응용 프로그램에서는 발생하지 않습니다.

그래서 좀 더 파고 난 후에 플래그 변수를 설정하기위한 권장 사항을 보았습니다. 필자의 경우이 문제는 설정하려고하지만 모든 것이 비동기 적이므로 해시 변경의 if 문에 대해 항상 제 시간에 설정되지는 않는다는 것입니다. .onMouseDown클릭에서 항상 호출 된 것은 아니며 onclick에 추가해도 충분히 빠르게 트리거되지는 않습니다.

나는 사이의 차이를보고 시작했을 때이다 document,하고 window. 마지막 해결책은을 사용하여 플래그를 설정하고을 사용하여 document.onmouseover비활성화하는 것 document.onmouseleave입니다.

사용자의 마우스가 문서 영역 안에있는 동안 (읽기 : 렌더링 된 페이지이지만 브라우저 프레임 제외) 내 부울이로 설정됩니다 true. 마우스가 문서 영역을 벗어나면 부울이로 바뀝니다 false.

이 방법 window.onhashchange으로 다음을 변경할 수 있습니다 .

window.onhashchange = function() {
    if (window.innerDocClick) {
        window.innerDocClick = false;
    } else {
        if (window.location.hash != '#undefined') {
            goBack();
        } else {
            history.pushState("", document.title, window.location.pathname);
            location.reload();
        }
    }
}

확인 표시가 나타납니다 #undefined. 내 배열에 사용 가능한 기록이 없으면을 반환하기 때문 undefined입니다. 나는 이것을 사용하여 사용자가 window.onbeforeunload이벤트를 사용하여 떠나기를 원하는지 묻습니다 .

즉, 페이지 내 뒤로 버튼이나 배열을 사용하여 기록을 저장하지 않아도되는 사람들을 위해 :

document.onmouseover = function() {
    //User's mouse is inside the page.
    window.innerDocClick = true;
}

document.onmouseleave = function() {
    //User's mouse has left the page.
    window.innerDocClick = false;
}

window.onhashchange = function() {
    if (window.innerDocClick) {
        //Your own in-page mechanism triggered the hash change
    } else {
        //Browser back button was clicked
    }
}

그리고 거기 있습니다. 해시 탐색과 관련하여 뒤로 버튼 사용과 인 페이지 요소를 감지하는 간단한 3 가지 방법입니다.

편집하다:

사용자가 백 스페이스를 사용하여 백 이벤트를 트리거하지 않도록 다음을 포함 할 수도 있습니다 ( 이 질문대한 @thetoolman 감사 ).

$(function(){
    /*
     * this swallows backspace keys on any non-input element.
     * stops backspace -> back
     */
    var rx = /INPUT|SELECT|TEXTAREA/i;

    $(document).bind("keydown keypress", function(e){
        if( e.which == 8 ){ // 8 == backspace
            if(!rx.test(e.target.tagName) || e.target.disabled || e.target.readOnly ){
                e.preventDefault();
            }
        }
    });
});

다음 popstate과 같은 이벤트 핸들러 를 시도 할 수 있습니다 .

window.addEventListener('popstate', function(event) {
    // The popstate event is fired each time when the current history entry changes.

    var r = confirm("You pressed a Back button! Are you sure?!");

    if (r == true) {
        // Call Back button programmatically as per user confirmation.
        history.back();
        // Uncomment below line to redirect to the previous page instead.
        // window.location = document.referrer // Note: IE11 is not supporting this.
    } else {
        // Stay on the current page.
        history.pushState(null, null, window.location.pathname);
    }

    history.pushState(null, null, window.location.pathname);

}, false);

참고 : 최상의 결과를 얻으려면 다른 예기치 않은 문제를 피하기 위해 논리를 구현하려는 특정 페이지에만이 코드를로드해야합니다.

popstate 이벤트는 현재 히스토리 항목이 변경 될 때마다 발생합니다 (사용자가 새 상태로 이동). 즉 브라우저의 뒤로 / 앞으로 버튼이나 경우에 사용자가 클릭 할 때 발생 history.back(), history.forward(), history.go()방법이 프로그래밍 방식이라고합니다.

event.state이벤트 is 속성은 기록 상태 개체와 같습니다.

jQuery 구문의 경우 문서를 준비한 후 리스너를 추가하기 위해 감싸십시오.

(function($) {
  // Above code here.
})(jQuery);

참조 : 페이지로드시 window.onpopstate


단일 페이지 앱 및 HTML5 pushState 페이지 의 예제도 참조 하십시오.

<script>
// jQuery
$(window).on('popstate', function (e) {
    var state = e.originalEvent.state;
    if (state !== null) {
        //load content with ajax
    }
});

// Vanilla javascript
window.addEventListener('popstate', function (e) {
    var state = e.state;
    if (state !== null) {
        //load content with ajax
    }
});
</script>

Chrome 5 이상, Firefox 4 이상, IE 10 이상, Safari 6 이상, Opera 11.5 이상과 호환되어야합니다.


나는이 요구 사항을 꽤 오랫동안 고투하고 있었고 위의 솔루션 중 일부를 구현했습니다. 그러나 나는 관찰을 우연히 발견했으며 Chrome, Firefox 및 Safari 브라우저 + Android 및 iPhone에서 작동하는 것 같습니다.

페이지로드시 :

window.history.pushState({page: 1}, "", "");

window.onpopstate = function(event) {

  // "event" object seems to contain value only when the back button is clicked
  // and if the pop state event fires due to clicks on a button
  // or a link it comes up as "undefined" 

  if(event){
    // Code to handle back button or prevent from navigation
  }
  else{
    // Continue user action through link or button
  }
}

이것이 도움이되는지 알려주십시오. 빠진 것이 있으면 기꺼이 이해하겠습니다.


자바 스크립트에서 탐색 유형 2은 브라우저의 뒤로 또는 앞으로 버튼 클릭을 의미하며 브라우저는 실제로 캐시에서 콘텐츠를 가져옵니다.

if(performance.navigation.type == 2)
{
    //Do your code here
}

이것은 확실히 작동합니다 (뒤로 버튼 클릭을 감지하기 위해)

$(window).on('popstate', function(event) {
 alert("pop");
});

브라우저 : https://jsfiddle.net/Limitlessisa/axt1Lqoz/

모바일 제어 : https://jsfiddle.net/Limitlessisa/axt1Lqoz/show/

$(document).ready(function() {
  $('body').on('click touch', '#share', function(e) {
    $('.share').fadeIn();
  });
});

// geri butonunu yakalama
window.onhashchange = function(e) {
  var oldURL = e.oldURL.split('#')[1];
  var newURL = e.newURL.split('#')[1];

  if (oldURL == 'share') {
    $('.share').fadeOut();
    e.preventDefault();
    return false;
  }
  //console.log('old:'+oldURL+' new:'+newURL);
}
.share{position:fixed; display:none; top:0; left:0; width:100%; height:100%; background:rgba(0,0,0,.8); color:white; padding:20px;
<!DOCTYPE html>
<html>

<head>
    <title>Back Button Example</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

</head>

<body style="text-align:center; padding:0;">
    <a href="#share" id="share">Share</a>
    <div class="share" style="">
        <h1>Test Page</h1>
        <p> Back button press please for control.</p>
    </div>
</body>

</html>


여기 내가 가져 가라. URL이 변경되었지만 document감지 된 내부에 클릭이 없을 경우 브라우저가 뒤로 (예 또는 앞으로) 있다고 가정합니다. Ajax를 통해 컨텐츠를로드하는 페이지에서이 작업을 수행하려면 2 초 후에 사용자 클릭이 재설정됩니다.

(function(window, $) {
  var anyClick, consoleLog, debug, delay;
  delay = function(sec, func) {
    return setTimeout(func, sec * 1000);
  };
  debug = true;
  anyClick = false;
  consoleLog = function(type, message) {
    if (debug) {
      return console[type](message);
    }
  };
  $(window.document).click(function() {
    anyClick = true;
    consoleLog("info", "clicked");
    return delay(2, function() {
      consoleLog("info", "reset click state");
      return anyClick = false;
    });
  });
  return window.addEventListener("popstate", function(e) {
    if (anyClick !== true) {
      consoleLog("info", "Back clicked");
      return window.dataLayer.push({
        event: 'analyticsEvent',
        eventCategory: 'test',
        eventAction: 'test'
      });
    }
  });
})(window, jQuery);

페이지 하단에이 코드를 추가했습니다. 브라우저 baack 감지 버튼을 참조하십시오

window.addEventListener("pageshow", function(e) {
  var is_back = e.persisted || (typeof window.performance !=
    "undefined" && window.performance.navigation.type === 2);
  if (is_back) {
    // do the action. 
  }
});

I did this task with trick above.added event listener which gets called when someone comes back to the page with browser back button and at that event just reloaded the page. Hope that helps.


See this:

history.pushState(null, null, location.href);
    window.onpopstate = function () {
        history.go(1);
    };

it works fine...


Correct answer is already there to answer the question. I want to mention new JavaScript API PerformanceNavigationTiming, it's replacing deprecated performance.navigation.

Following code will log in console "back_forward" if user landed on your page using back or forward button. Take a look at compatibility table before using it in your project.

var perfEntries = performance.getEntriesByType("navigation");
for (var i = 0; i < perfEntries.length; i++) {
    console.log(perfEntries[i].type);
}

The document.mouseover does not work for IE and FireFox. However I have tried this :

$(document).ready(function () {
  setInterval(function () {
    var $sample = $("body");
    if ($sample.is(":hover")) {
      window.innerDocClick = true;
    } else {
      window.innerDocClick = false;
    }
  });

});

window.onhashchange = function () {
  if (window.innerDocClick) {
    //Your own in-page mechanism triggered the hash change
  } else {
    //Browser back or forward button was pressed
  }
};

This works for Chrome and IE and not FireFox. Still working to get FireFox right. Any easy way on detecting Browser back/forward button click are welcome, not particularly in JQuery but also AngularJS or plain Javascript.


 <input style="display:none" id="__pageLoaded" value=""/>


 $(document).ready(function () {
        if ($("#__pageLoaded").val() != 1) {

            $("#__pageLoaded").val(1);


        } else {
            shared.isBackLoad = true;
            $("#__pageLoaded").val(1);  

            // Call any function that handles your back event

        }
    });

The above code worked for me. On mobile browsers, when the user clicked on the back button, we wanted to restore the page state as per his previous visit.


I was able to use some of the answers in this thread and others to get it working in IE and Chrome/Edge. history.pushState for me wasn't supported in IE11.

if (history.pushState) {
    //Chrome and modern browsers
    history.pushState(null, document.title, location.href);
    window.addEventListener('popstate', function (event) {
        history.pushState(null, document.title, location.href);
    });
}
else {
    //IE
    history.forward();
}

I solved it by keeping track of the original event that triggered the hashchange (be it a swipe, a click or a wheel), so that the event wouldn't be mistaken for a simple landing-on-page, and using an additional flag in each of my event bindings. The browser won't set the flag again to false when hitting the back button:

var evt = null,
canGoBackToThePast = true;

$('#next-slide').on('click touch', function(e) {
    evt = e;
    canGobackToThePast = false;
    // your logic (remember to set the 'canGoBackToThePast' flag back to 'true' at the end of it)
}

if (window.performance && window.performance.navigation.type == window.performance.navigation.TYPE_BACK_FORWARD) {
  alert('hello world');
}

This is the only one solution that worked for me (it's not a onepage website). It's working with Chrome, Firefox and Safari.


I tried the above options but none of them is working for me. Here is the solution

if(window.event)
   {
        if(window.event.clientX < 40 && window.event.clientY < 0)
        {
            alert("Browser back button is clicked...");
        }
        else
        {
            alert("Browser refresh button is clicked...");
        }
    }

Refer this link http://www.codeproject.com/Articles/696526/Solution-to-Browser-Back-Button-Click-Event-Handli for more details

참고URL : https://stackoverflow.com/questions/25806608/how-to-detect-browser-back-button-event-cross-browser

반응형