사용자가 뒤로 버튼을 사용하여 페이지에 접속했는지 여부를 감지하려면 어떻게 해야 합니까?
이 질문은 사용자가 브라우저의 [Track]버튼을 눌렀을 때의 [Track](추적)과 비슷하지만 동일하지는 않습니다.저는 해결책을 가지고 있으며 참고와 피드백을 위해 여기에 게시합니다.더 좋은 방법이 있다면, 난 귀 기울여 듣겠어!
「편집」이라고 하는, 플리커가 있는 페이지가 있는 경우입니다.예를 들어, "설명을 추가하려면 여기를 클릭하십시오" DIV가 있으며, 이 DIV를 클릭하면 저장 및 취소 버튼이 있는 TEXTAREA로 바뀝니다.[저장(Save)]를 클릭하면 데이터가 서버에 게시되어 데이터베이스가 갱신되고 TEXTAREA 대신 새로운 설명이 DIV에 저장됩니다.페이지가 새로 고쳐지면 "편집하려면 클릭" 옵션을 사용하여 데이터베이스에서 새 설명이 표시됩니다.요즘은 웹 2.0을 꽤 표준으로 사용하고 있습니다.
문제는 다음과 같은 경우입니다.
- 설명 없이 페이지가 로드됩니다.
- 설명이 사용자에 의해 추가됨
- 페이지를 이동하려면 링크를 클릭합니다.
- 사용자가 뒤로 버튼을 클릭하다
(브라우저 캐시에서) 표시되는 것은 새로운 설명을 포함하는 동적으로 수정된 DIV가 없는 페이지 버전입니다.
이는 사용자가 업데이트가 손실되었다고 가정하고 변경 내용을 보기 위해 페이지를 새로 고칠 필요가 있다는 것을 반드시 이해하지 못하기 때문에 매우 큰 문제입니다.
자, 질문은 다음과 같습니다.페이지가 로드된 후 수정되었다고 플래그를 지정한 후 사용자가 "다시 페이지로 돌아가는" 시기를 감지하고 이 상황에서 강제로 새로 고치려면 어떻게 해야 합니까?
숨김 형식을 사용합니다.다시 로드하거나 뒤로 버튼을 눌러 페이지로 돌아가면 양식 데이터가 브라우저에 보존됩니다(일반적으로).페이지에는 다음과 같은 내용이 표시됩니다(아마 하단 부근).
<form name="ignore_me">
<input type="hidden" id="page_is_dirty" name="page_is_dirty" value="0" />
</form>
Javascript에서는 다음 사항이 필요합니다.
var dirty_bit = document.getElementById('page_is_dirty');
if (dirty_bit.value == '1') window.location.reload();
function mark_page_dirty() {
dirty_bit.value = '1';
}
폼을 스니핑하는 js는 html이 완전히 해석된 후에 실행해야 하지만 사용자 지연이 심각한 경우 폼과 js를 페이지 맨 위에 둘 수 있습니다(js 초).
여기 이 오래된 문제에 대한 아주 쉬운 현대적인 해결책이 있다.
if (window.performance && window.performance.navigation.type === window.performance.navigation.TYPE_BACK_FORWARD) {
alert('Got here using the browser "Back" or "Forward" button.');
}
window.performance는 현재 모든 주요 브라우저에서 지원됩니다.
이 글에서 설명하고 있습니다.다음 코드를 참조하십시오.http://www.webkit.org/blog/516/webkit-page-cache-ii-the-unload-event/
<html>
<head>
<script>
function pageShown(evt){
if (evt.persisted) {
alert("pageshow event handler called. The page was just restored from the Page Cache (eg. From the Back button.");
} else {
alert("pageshow event handler called for the initial load. This is the same as the load event.");
}
}
function pageHidden(evt){
if (evt.persisted) {
alert("pagehide event handler called. The page was suspended and placed into the Page Cache.");
} else {
alert("pagehide event handler called for page destruction. This is the same as the unload event.");
}
}
window.addEventListener("pageshow", pageShown, false);
window.addEventListener("pagehide", pageHidden, false);
</script>
</head>
<body>
<a href="http://www.webkit.org/">Click for WebKit</a>
</body>
</html>
최신 브라우저에서는 이것이 올바른 방법인 것 같습니다.
const perfEntries = performance.getEntriesByType('navigation');
if (perfEntries.length && perfEntries[0].type === 'back_forward') {
console.log('User got here from Back or Forward button.');
}
이것은 2020년 1월 현재도 「실험적」이지만, 잘 서포트되고 있는 것 같습니다.
https://developer.mozilla.org/en-US/docs/Web/API/PerformanceNavigationTiming
이 문제는 언로드 전 이벤트를 사용하여 해결할 수 있습니다.
window.onbeforeunload = function () { }
언로드 전 빈 이벤트 매니저 기능이 있다는 것은 페이지가 액세스할 때마다 다시 작성된다는 것을 의미합니다.Javascripts가 재실행되고 서버측 스크립트가 재실행되며, 이 페이지는 사용자가 뒤로 또는 앞으로 버튼을 누르는 것만으로 페이지에 도달하더라도 사용자가 처음 입력하는 것처럼 작성됩니다.
다음은 예시의 전체 코드입니다.
<html>
<head>
<title>onbeforeunload.html</title>
<script>
window.onbeforeunload = function () { }
function myfun()
{
alert("The page has been refreshed.");
}
</script>
<body onload="myfun()">
Hello World!<br>
</body>
</html>
시도하고 이 페이지를 이동한 다음 브라우저의 "뒤로" 또는 "앞으로" 단추를 사용하여 돌아가십시오.
IE, FF, Chrome에서는 정상적으로 동작합니다.
물론 내 fun 기능 안에서 네가 하고 싶은 건 뭐든지 할 수 있어.
상세정보 : http://www.hunlock.com/blogs/Mastering_The_Back_Button_With_Javascript
local스토리지 또는 session스토리지(http://www.w3schools.com/html/html5_webstorage.asp)를 사용하여 플래그를 설정할 수 있습니다(숨김 양식 사용 금지).
위와 같이 저는 해결책을 찾아 참고와 피드백을 위해 여기에 게시합니다.
솔루션의 첫 번째 단계는 페이지에 다음 항목을 추가하는 것입니다.
<!-- at the top of the content page -->
<IFRAME id="page_is_fresh" src="fresh.html" style="display:none;"></IFRAME>
<SCRIPT style="text/javascript">
function reload_stale_page() { location.reload(); }
</SCRIPT>
★★★의 fresh.html
치 않기 다음 합니다.
<!-- fresh.html -->
<HTML><BODY></BODY></HTML>
클라이언트측 코드가 페이지를 갱신할 때는, 다음과 같이 변경에 플래그를 붙여야 합니다.
function trigger_reload_if_user_clicks_back_button()
{
// "dis-arm" the reload stale page function so it doesn't fire
// until the page is reloaded from the browser's cache
window.reload_stale_page = function(){};
// change the IFRAME to point to a page that will reload the
// page when it loads
document.getElementById("page_is_fresh").src = "stale.html";
}
stale.html
모든 작업을 수행합니다.되,, 이이 the the the the the the the the the 라고 합니다.reload_stale_page
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★때에는, 「 」( 「 」, 「 」), 「 」( 「 」),reload_stale_page
을 사용하다
<!-- stale.html -->
<HTML><BODY>
<SCRIPT type="text/javascript">window.parent.reload_stale_page();</SCRIPT>
</BODY></HTML>
이 단계에서 실시한 (최소한의) 테스트에서는, 이것은 기대대로 동작하고 있는 것 같습니다.제가 뭘 간과했나요?
다음은 jQuery 버전입니다.사용자가 뒤로 버튼을 누르면 Safari 데스크톱/모바일이 캐시를 처리하는 방식 때문에 몇 번인가 사용할 필요가 있었습니다.
$(window).bind("pageshow", function(event) {
if (event.originalEvent.persisted) {
// Loading from cache
}
});
이 페이지, 특히 @Nick White의 답변에 대한 @sajith의 코멘트와 http://www.mrc-productivity.com/techblog/?p=1235 페이지를 사용합니다.
<form name="ignore_me" style="display:none">
<input type="text" id="reloadValue" name="reloadValue" value="" />
</form>
$(function ()
{
var date = new Date();
var time = date.getTime();
if ($("#reloadValue").val().length === 0)
{
$("#reloadValue").val(time);
}
else
{
$("#reloadValue").val("");
window.location.reload();
}
});
오늘 비슷한 문제가 발생했는데 localStorage로 해결했습니다(여기 jQuery를 조금 사용).
$(function() {
if ($('#page1').length) {
// this code must only run on page 1
var checkSteps = function () {
if (localStorage.getItem('steps') == 'step2') {
// if we are here, we know that:
// 1. the user is on page 1
// 2. he has been on page 2
// 3. this function is running, which means the user has submitted the form
// 4. but steps == step2, which is impossible if the user has *just* submitted the form
// therefore we know that he has come back, probably using the back button of his browser
alert('oh hey, welcome back!');
} else {
setTimeout(checkSteps, 100);
}
};
$('#form').on('submit', function (e) {
e.preventDefault();
localStorage.setItem('steps', 'step1'); // if "step1", then we know the user has submitted the form
checkOrderSteps();
// ... then do what you need to submit the form and load page 2
});
}
if ($('#page2').length) {
// this code must only run on page 2
localStorage.setItem('steps', 'step2');
}
});
Si 기본:
1페이지에서 사용자가 양식을 제출하면 localStorage에 사용자가 어떤 조치를 취했는지를 나타내는 값 "스텝"을 설정합니다.동시에 타임아웃이 있는 함수를 기동하여 이 값이 변경되었는지 확인합니다(예: 10회/초).
2페이지에서는 해당 값을 즉시 변경합니다.
따라서 사용자가 뒤로 버튼을 사용하여 브라우저가 페이지 1을 떠날 때와 동일한 상태로 복원하는 경우 checkSteps 기능은 여전히 실행 중이며 localStorage의 값이 변경되었음을 감지할 수 있습니다(또한 적절한 조치를 취할 수 있습니다).이 체크가 목적에 도달하면 계속 실행할 필요가 없기 때문에 set Timeout을 사용하지 않습니다.
이것을 다른 사람의 코멘트에서 찾았습니다(Mladen씨 감사합니다). Chrome 88에서는 매우 잘 동작하는 것 같습니다.
if(String(window.performance.getEntriesByType("navigation")[0].type) === "back_forward"){
// Actions here, such as refresh page, etc.
}
몇 시간 동안 이 토끼굴을 파고들었더니, 이게 드디어 내게 가장 잘 맞는 해결책이야.
window.addEventListener('pageshow', function (event) {
if (event.persisted || performance.getEntriesByType("navigation")[0].type === 'back_forward') {
// DO STUFF HERE
}
});
performance.getEntriesByType()
엣지와 파이어폭스 모두에서 정상적으로 동작하고 있었지만, Chrome에서는 일관성이 없는 결과를 얻을 수 있었습니다.어떤 경우엔, 나는 어떤 타입을 얻곤 했다.'back_forward'
예상대로지만, 다른 때는 원래 네비게이션 타입이 무엇이든 그 페이지로 이동하여 다시 돌아오곤 했습니다(즉,'navigate'
또는'reload'
대신'back_forward'
(백버튼을 사용하여 페이지에 도달한 경우에도)
event.persisted
Chrome에서는 잘 동작했지만 Edge에서는 전혀 동작하지 않는 것 같습니다.
지금까지 Chrome, Edge, Firefox에서는 이 둘을 조합하는 것이 일관되게 효과가 있었습니다.
또한 TypeScript에서 동작하도록 하기 위해 비트를 교체했습니다.||
와 함께(performance.getEntriesByType("navigation")[0] as PerformanceNavigationTiming).type === 'back_forward'
(Chrome 108, Edge 108 및 Firefox 107에서만 테스트됨)
언급URL : https://stackoverflow.com/questions/829046/how-do-i-detect-if-a-user-has-got-to-a-page-using-the-back-button
'programing' 카테고리의 다른 글
리액트 JS에서 이미지를 업로드하는 방법 (0) | 2023.02.22 |
---|---|
JSONObject에서 값 유형을 확인하려면 어떻게 해야 합니까? (0) | 2023.02.22 |
setInterval()을 사용한 간단한 연속 폴링 실행 (0) | 2023.02.22 |
null과 undefined를 모두 확인할 수 있는 방법이 있을까요? (0) | 2023.02.22 |
WordPress 로딩 jQuery 및 jQuery-migrate를 중지하려면 어떻게 해야 합니까? (0) | 2023.02.22 |