[javascript] 브라우저 뒤로 버튼 이벤트를 감지하는 방법-크로스 브라우저
사용자가 브라우저에서 뒤로 버튼을 눌렀는지 여부를 어떻게 정확하게 감지합니까?
#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);
단일 페이지 앱 및 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");
});
답변
이것 좀 봐:
history.pushState(null, null, location.href);
window.onpopstate = function () {
history.go(1);
};
잘 작동합니다 …
답변
if (window.performance && window.performance.navigation.type == window.performance.navigation.TYPE_BACK_FORWARD) {
alert('hello world');
}
이것은 나를 위해 일한 유일한 솔루션입니다 (onepage 웹 사이트는 아닙니다). Chrome, Firefox 및 Safari에서 작동합니다.