뒤로 버튼을 클릭 할 때 크로스 브라우저 onload 이벤트가 있습니까?


185

모든 주요 브라우저 (IE 제외) onload의 경우 뒤로 버튼 작업의 결과로 페이지가로드 될 때 JavaScript 이벤트가 시작되지 않으며 페이지가 처음로드 될 때만 실행됩니다.

누군가이 문제를 해결하는 샘플 크로스 브라우저 코드 (Firefox, Opera, Safari, IE 등)를 알려 줄 수 있습니까? 나는 Firefox의 pageshow이벤트에 익숙 하지만 불행히도 Opera 나 Safari는 이것을 구현하지 않습니다.


6
이것은 문제가되지 않습니다. 사용자가 뒤로 버튼을 누를 때 웹 페이지를 빠르게로드 할 수 있습니다. 자세한 내용은 아래 답변을 참조하십시오. 여기에서 제안 된 해결 방법은 뒤로 / 앞으로 탐색이 느리기 때문에 웹 페이지를 사용자에게 더 성가 시게합니다.
Nickolay

2
@romkyns : 귀하의 의견은이 질문과 관련이 없습니다. 브라우저가 JS / DOM 상태를 복원하지 않으면로드 이벤트가 발생합니다.
Nickolay

아이폰 OS 5+ 역사의 뒤로 버튼 여기에 해결 stackoverflow.com/a/12652160/1090395
믈라덴 Janjetovic에게

답변:


117

여러분, JQuery에는 한 가지 효과 만 있습니다. 뒤로 버튼을 누르면 페이지가 다시로드됩니다. 이것은 " 준비 " 와 관련이 없습니다 .

어떻게 작동합니까? JQuery는 onunload 이벤트 리스너를 추가합니다 .

// http://code.jquery.com/jquery-latest.js
jQuery(window).bind("unload", function() { // ...

기본적으로 아무 것도 수행하지 않습니다. 그러나 어떻게 든 이벤트 핸들러에 포함되어 있든 Safari, Opera 및 Mozilla에서 다시로드를 트리거하는 것처럼 보입니다.

[ edit (Nickolay) : 다음과 같이 작동합니다 : webkit.org , developer.mozilla.org . 그 제품 (이하 별도의 대답에 내 요약)를 읽고 여부를 고려하시기 바랍니다 정말 이 작업을 수행하고 사용자에게 느린 페이지로드를 확인해야합니다.]

믿을 수 없습니까? 이 시도:

<body onunload=""><!-- This does the trick -->
<script type="text/javascript">
    alert('first load / reload');
    window.onload = function(){alert('onload')};
</script>
<a href="http://stackoverflow.com">click me, then press the back button</a>
</body>

JQuery를 사용할 때 비슷한 결과가 나타납니다.

onunload 없이 이것과 비교하고 싶을 수도 있습니다.

<body><!-- Will not reload on back button -->
<script type="text/javascript">
    alert('first load / reload');
    window.onload = function(){alert('onload')};
</script>
<a href="http://stackoverflow.com">click me, then press the back button</a>
</body>

1
비록 문서화되지 않은 기능 / 버그이지만, 차기 버전의 브라우저에서 작동을 멈출 수도 있지만 여전히 흥미 롭습니다.
Wadih M.

3
이것은 또한 잘 작동합니다 (onunload = ""부분을 잊지 마십시오, 그렇지 않으면 ff3에서는 작동하지 않습니다) : <body onload = "alert ( 'onload');" onunload = "">
Wadih M.

3
브라우저에 페이지에 onunload핸들러 가있는 경우 페이지를 캐시 할 수 없다고 가정하기 때문입니다 (페이지가 이미 모든 것을 파괴했습니다. 왜 캐시합니까?).
Casey Chu

14
최신 브라우저에서 답이 작동하지 않는 것 같습니다-최신 Chrome 및 Opera에서 확인
Andrew

10
그것은 iPad 사파리에서 작동하지 않습니다 ... 제발, 답변으로 표시 해제
xus

74

일부 최신 브라우저 (Firefox, Safari 및 Opera (Chrome은 아님))는 사용자가 뒤로 탐색 할 때 포함되는 특수한 "뒤로 / 앞으로"캐시 (모질라가 개발 한 용어 인 bfcache라고 함)를 지원합니다. 일반 (HTTP) 캐시와 달리 페이지의 전체 상태 (JS, DOM 상태 포함)를 캡처합니다. 이를 통해 사용자가 페이지를 더 정확하게 페이지를 다시로드 할 수 있습니다.

그만큼 load페이지가이 bfcache에서로드 될 때 이벤트는 화재되어 있지 않습니다. 예를 들어, "load"핸들러에서 UI를 작성하고 "load"이벤트가 초기로드시 한 번 발생하고 두 번째로 bfcache에서 페이지가 다시로드되면 페이지가 종료됩니다. UI 요소를 복제합니다.

이것이 "언로드"핸들러를 추가하면 페이지가 bfcache에 저장되는 것을 막는 이유입니다 (따라서 탐색 속도가 느려짐). 언로드 핸들러가 정리 작업을 수행하여 페이지를 실행 불가능한 상태로 유지할 수 있습니다.

언제 탐색 / 이동하는지 알 필요가있는 페이지의 경우, Firefox 1.5 이상 및 Safari 28758 수정 버전의 Safari 버전은 "pageshow"및 "pagehide"라는 특수 이벤트를 지원합니다.

참고 문헌 :


정말 멋지다. 나는 현재 내 dom 조작이 bfcache에 저장되지 않은 것처럼 보입니다. 예상 할 수있는 상황이 있습니까?
벤슨

1
@ Benson : Firefox가 bfcache에 페이지를 저장하지 않는 가능한 이유는 내가 연결된 dev.mo 페이지에 나와 있습니다. 페이지를 bfcache에 저장할 수는 없지만 특정 DOM 상태는 저장되지 않는다고 생각합니다.
Nickolay

Nickolay, 나는 당신의 재로드를 강요하고 bfcache가 수행 한 좋은 작업을 취소하기를 꺼려하지만 bfcache에서 페이지의 dom을 업데이트하는 다른 방법이 있습니까? 예를 들어, 메시지 목록이있는 페이지에서 그 중 하나의 페이지로 이동하는 상황을 고려하고 "뒤로"이동할 때 읽기 / 읽기 표시기가 변경되기를 원합니다. 페이지를 다시로드하지 않고 어떻게 할 수 있습니까?
그렉

@ 그렉 : 당신은 페이지를 제어하는 ​​개발자를 의미합니까? 'pageshow'리스너에서 아약스 요청을 발생시킵니다.
Nickolay

jQuery를 사용하고 빠른 bfcache 지원을 얻는 방법에 대한 아이디어가 있습니까?
Alex Black

31

사용자가 뒤로 또는 앞으로 클릭했을 때 js가 실행되지 않는 문제가 발생했습니다. 먼저 브라우저 캐싱을 중지하기로 설정했지만 이것이 문제가되지는 않았습니다. 모든 라이브러리 등이로드 된 후 내 자바 스크립트가 실행되도록 설정되었습니다. readyStateChange 이벤트로 확인했습니다.

일부 테스트 후 뒤로 클릭 한 페이지에서 요소의 readyState가 '로드'되지 않고 '완료'인 것을 알았습니다. || element.readyState == 'complete'조건문에 추가하면 문제가 해결되었습니다.

내가 찾은 결과를 공유하겠다고 생각했는데 다른 사람들을 도울 수 있기를 바랍니다.

완전성을 위해 편집

내 코드는 다음과 같습니다.

script.onreadystatechange(function(){ 
   if(script.readyState == 'loaded' || script.readyState == 'complete') {
      // call code to execute here.
   } 
});

위의 코드 샘플에서 스크립트 변수는 DOM에 추가 된 새로 작성된 스크립트 요소입니다.


7
이것을 어디에 추가 했습니까? 그리고 사용자가 반격 한 후 어떤 일이 발생 했습니까? 코드를 보여주세요!
Keerigan

"내 조건문"이라고 할 때 무슨 뜻입니까?
Phillip Senn

1
@Phillip 조건문은 if 문입니다.
Brian Heese

22

여기, ckramer의 초기 솔루션과 Opera를 포함한 모든 브라우저에서 작동하는 palehorse의 예를 기반으로 한 최종 솔루션이 있습니다. history.navigationMode를 'compatible'로 설정하면 jQuery의 ready 함수는 Opera와 다른 주요 브라우저에서 뒤로 버튼 조작시 실행됩니다.

이 페이지에는 자세한 정보가 있습니다.

예:

history.navigationMode = 'compatible';
$(document).ready(function(){
  alert('test');
});

나는 이것을 Opera 9.5, IE7, FF3 및 Safari에서 테스트했으며 모두 작동합니다.


2
분명히 (약 5.5 년) 지났지 만 연결이 끊어 졌음을 주목할 가치가 있습니다.
Jeff

2
이 솔루션은 저에게 효과적이지 않습니다. 최신 Firefox (45.0.1)에서이 문제가 발생했습니다.
Armin

6

위의 예제를 작동시킬 수 없었습니다. 뒤로 버튼을 통해 페이지로 돌아올 때 수정 된 특정 div 영역을 새로 고치기를 원했습니다. 내가 사용한 트릭은 div 영역이 원래 영역에서 변경 되 자마자 숨겨진 입력 필드 ( "더티 비트"라고 함)를 1로 설정하는 것입니다. 숨겨진 입력 필드는 실제로 다시 클릭 할 때 해당 값을 유지하므로 onload 에서이 비트를 확인할 수 있습니다. 설정되면 페이지를 새로 고칩니다 (또는 div를 새로 고칩니다). 그러나 원래로드에서는 비트가 설정되지 않으므로 페이지를 두 번로드하는 데 시간을 낭비하지 않습니다.

<input type='hidden' id='dirty'>

<script>
$(document).ready(function() {
  if ($('#dirty').val()) {
    // ... reload the page or specific divs only
  }
  // when something modifies a div that needs to be refreshed, set dirty=1
  $('#dirty').val('1');
});
</script>

뒤로 버튼을 클릭 할 때마다 올바르게 트리거됩니다.


3
Firefox에서는 작동하지 않지만 숨겨진 필드의 지속성이 매우 유용한 IE / Chrome의 상황을 처리하는 교묘 한 방법이라고 생각합니다. 귀하의 트릭과 "pageshow"이벤트를 사용 했으므로 모든 기본 브라우저를 다룹니다.
Magnus Smith

이것이 작동하는 pageshow에서 작동하지 않는 브라우저는 무엇입니까?
저스틴

4

올바르게 기억한다면 unload () 이벤트를 추가하면 페이지를 캐시 할 수 없다는 것을 의미합니다 (앞으로 / 뒤로 캐시로). 사용자가 멀리 이동할 때 상태가 변경되거나 변경 될 수 있기 때문입니다. 따라서 기록 개체를 탐색하여 페이지로 돌아올 때 페이지의 마지막 초 상태를 복원하는 것은 안전하지 않습니다.


4

"뒤로"를 칠 때 이벤트 발생에 대해 이야기하지 않았기 때문에 이것이 페이지로드가 아닌 "onunload"에 대한 것이라고 생각 했습니까? $ document.ready ()는 페이지로 이동하는 방법에 관계없이 페이지로드시 원하는 이벤트를위한 것입니다 (예 : 리디렉션, 브라우저를 URL로 직접 여는 등). 이전 페이지가 다시로드 될 때 실행되는 정보 그리고 $ document.ready ()가 포함되어 있어도 Javascript가 여전히 있다는 것을 알았으므로 페이지가 캐시되지 않는지 확실하지 않습니다. 우리는 스크립트를 수정할 때마다이 이벤트가있는 스크립트를 편집 할 때 Ctrl + F5를 눌러야하고 페이지에서 결과를 테스트하려고합니다.

$(window).unload(function(){ alert('do unload stuff here'); }); 

"뒤로"를 누르고 현재 페이지를 언로드 할 때 onunload 이벤트에 대해 원하는 것이며, 사용자가 브라우저 창을 닫을 때도 실행됩니다. 이것은 $ document.ready () 응답으로 수를 초과하더라도 원하는 것 같습니다. 기본적으로 현재 페이지가 닫히는 동안 발생하는 이벤트 발생 또는로드 될 때 "뒤로"를 클릭 할 때로드되는 이벤트 발생의 차이점이 있습니다. IE 7에서 잘 테스트되었으므로 다른 브라우저는 우리가있는 곳에서 허용되지 않으므로 말할 수 없습니다. 그러나 이것은 다른 옵션 일 수 있습니다.


4

jQuery의 준비된 이벤트가 IE 및 FireFox에서 작동한다는 것을 ckramer에게 확인할 수 있습니다. 샘플은 다음과 같습니다.

<html>
<head>
    <title>Test Page</title>
    <script src="http://code.jquery.com/jquery-latest.js" type="text/javascript"></script>
    <script type="text/javascript">
            $(document).ready(function () {
               var d = new Date();
               $('#test').html( "Hi at " + d.toString() );
            });
    </script>
</head>
<body>
    <div id="test"></div>
    <div>
        <a href="http://www.google.com">Go!</a>
    </div>
</body>
</html>

4

전체 jquery 라이브러리를 사용하지 않으려는 사람들을 위해 별도의 코드로 구현을 추출했습니다. 크기는 0,4KB에 불과합니다.

다음 위키에서 독일어 학습서와 함께 코드를 찾을 수 있습니다. http://www.easy-coding.de/wiki/html-ajax-und-co/onload-event-cross-browser-kompatibler-domcontentloaded.html


1
론 링크는 그 자체로는 무의미하고 목표 자원이 미래에 살아 있음을 보장하지 않기 때문에 빈약 한 답변으로 간주됩니다 ( FAQ 참조 ) . 하는 것이 바람직 할 것이다 여기에 대한 대답의 본질적인 부분을 포함하고 참조 할 수 있도록 링크를 제공합니다.
j0k

3

jQuery의 준비 이벤트는 이런 종류의 문제를 위해 만들어졌습니다. 엄폐물 아래에서 무슨 일이 일어나고 있는지 알아보기 위해 구현을 파고 드는 것이 좋습니다.


6
오랫동안 ready뒤로 버튼을 사용할 때 Firefox에서 트리거되지 않는 것 같습니다. Nickolay의 답변 도 참조하십시오 .
Arjan

2

빌, 나는 당신의 질문에 감히 대답하지만, 내 추측으로는 100 % 확신하지 못합니다. 나는 역사상의 페이지로 사용자를 데려 갈 때 IE 브라우저 이외의 다른 브라우저는 캐시에서 페이지와 리소스를로드 할뿐만 아니라 페이지의 전체 DOM (읽기 세션) 상태를 복원한다고 생각합니다. IE는 DOM 복원을하지 않거나 (또는 ​​임대하지 않았으므로) 적절한 페이지 재 초기화에 onload 이벤트가 필요한 것으로 보입니다.


2

$ (document) .ready ...를 사용하여 Bill의 솔루션을 시도했지만 처음에는 작동하지 않았습니다. 스크립트가 html 섹션 뒤에 배치되면 작동하지 않는다는 것을 발견했습니다. 헤드 섹션 인 경우 IE에서만 작동합니다. Firefox에서는 스크립트가 작동하지 않습니다.


1

좋아, 나는 이것을 시도했고 Firefox 3, Safari 3.1.1 및 IE7에서는 작동하지만 Opera 9.52 에서는 작동 하지 않습니다 .
창백한 예를 기반으로 아래에 표시된 예를 사용하면 페이지가 처음로드 될 때 경고 상자 팝업이 표시됩니다. 그러나 다른 URL로 이동 한 다음 뒤로 버튼을 눌러이 페이지로 돌아 가면 Opera에서 경고 상자 팝업이 나타나지 않지만 다른 브라우저에서는 팝업 상자가 나타납니다.

어쨌든, 나는 이것이 지금까지 충분히 가깝다고 생각합니다. 모두 감사합니다!

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Untitled Document</title>
<meta http-equiv="expires" content="0">
<script src="jquery.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready( 
                    function(){
                      alert('test');
                    }
                 );
</script>
</head>
<body>
<h1>Test of the page load event and the Back button using jQuery</h1>
</body>
</html>

1

언로드 이벤트가 IE 9에서 제대로 작동하지 않습니다. load 이벤트 (onload ())로 시도했지만 IE 9FF5에서 올바르게 작동합니다 .

예:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
    jQuery(window).bind("load", function() {
        $("[name=customerName]").val('');
    });
</script>
</head>
<body>
    <h1>body.jsp</h1>
    <form action="success.jsp">
        <div id="myDiv">

        Your Full Name: <input name="yourName" id="fullName"
            value="Your Full Name" /><br> <br> <input type="submit"><br>

        </div>

    </form>
</body>
</html>

0

html 템플릿을 사용했습니다. 이 템플릿의 custom.js 파일에는 다음과 같은 기능이 있습니다.

    jQuery(document).ready(function($) {

       $(window).on('load', function() {
          //...
       });

    });

그러나 다른 페이지로 이동 한 후 돌아 가면이 기능이 작동하지 않았습니다.

그래서, 나는 이것을 시도하고 작동했습니다 :

    jQuery(document).ready(function($) {
       //...
    });

   //Window Load Start
   window.addEventListener('load', function() {
       jQuery(document).ready(function($) {
          //...
       });
   });

이제 2 "준비"기능이 있지만 오류가 발생하지 않으며 페이지가 잘 작동합니다.

그럼에도 불구하고 Windows 10-Opera v53 및 Edge v42에서 테스트되었지만 다른 브라우저는 테스트하지 않았다고 선언해야합니다. 이 점을 명심하십시오 ...

참고 : jquery 버전은 3.3.1이고 마이그레이션 버전은 3.0.0입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.