인라인 스크립트 태그 및 popstate와 일치하지 않는 행위

5025 단어 jquery-pjax

묘사

나는 페이지에 내연 스크립트 표시를 사용하여 데이터를javascript에 전달한다.예를 들면 다음과 같습니다.
<script type="text/javascript>
new Page({userId: 17, pageName: "blah", ... });
</script>
pjax를 사용할 때 사이트를 정상적으로 클릭할 수 있습니다.그러나 '후퇴/전진' 단추를 눌렀을 때 스크립트는 90% 의 시간 안에 실행되지 않을 것 같다. (때로는 무작위로 실행될 수도 있어 곤혹스럽다.)페이지 내용에 스크립트 표시가 놓여 있는 것을 볼 수 있습니다. pjax에서 container.html(contents) 줄을 실행하는 곳에 인터럽트를 놓고 팝업된 코드 세그먼트를 삽입할 때 스크립트 표시를 볼 수 있습니다.이상하게도 내가 용기를 수동으로 운행하면.html(내용)은 이 단점에서 내가 처음 그것을 실행할 때 내용이 교환되고 스크립트 표시가 실행되지 않는다.단, 만약 내가 그것을 두 번째로 실행한다면, 스크립트 표시는 계산되고 실행될 것이다.
이것은 나에게 아무런 의미가 없다. 왜냐하면 pjax 내부에서 사이트를 눌렀을 때 context.html(contents) 마운트된 내용만 삽입하고, popstate를 눌렀을 때와 같지만, 사이트를 눌렀을 때 스크립트 표시는 항상 실행되기 때문이다.이것은 pjax나 jquery의 오류입니까? 아니면 제가 무엇을 소홀히 했습니까?같은 행동도 크롬과 Firefox에서 일어났다.이 가능하다, ~할 수 있다,...https://github.com/defunkt/jquery-pjax/issues/48스크립트가 실행 중인 것을 제외하고 팝스테이트에서 일치하지 않습니다.jQuery1.9

토론 #1

를 사용하면 나도 같은 문제에 부딪혔다.제가 여기서 보도했었어요. defunkt/jquery pjax#235.
역사를 돌이켜보면 구글 지도에도 문제가 있다. 구글 지도는 어떤 방식으로 표시되지만, 지도 검색, 축소 기능은 전혀 작용하지 않는다.

토론 #2

내연 스크립트는 pjax에서 사용할 수 없습니다.

토론 #셋

드디어 알았어요.popstate에서 스크립트를 다시 실행할 수 없는 이유는 다음과 같습니다.http://jquery.com/upgrade-guide/1.9/#loading- html 콘텐츠에서 스크립트 실행
이 문제를 해결하려면 팝스테이트에서 스크립트 표시를 수동으로 다시 실행하십시오.그래서 너는 이렇게 할 수 있다.
$(document).on('pjax:popstate', function() {
   $(document).one('pjax:end', function(event) {
        $(event.target).find('script').each(function() {
            $.globalEval(this.text || this.textContent || this.innerHTML || '');
        })
   });
});
그리고 나는 이것이 일치하지 않는다고 잘못 생각했다.처음 pjaxed보다 더 먼 곳에 상태를 두었을 때만 일치하지 않습니다. 그래서 이런 상황에서 자바스크립트를 수동으로 페이지를 다시 불러올 뿐입니다. 모든 것이 정상인 것 같습니다.다시 불러오는 것도 피할 수 있을 것 같지만, 더 많은 테스트를 해서 확인해야 한다.popstate의 이런 재평가 스크립트도 pjax 자체에 직접 추가할 수 있습니다.
그래서 pjax에서 내장 스크립트를 사용할 수 있습니다. 팝스테이트의 일부 것만 처리하면 됩니다.그리고 jQuery1.9 이전에는 작동하지 않았습니다. 1.8 및 이전 버전은 실행 후 스크립트 표시를 완전히 제거하는 데 사용되었기 때문입니다. 스크립트 표시를run으로 표시하고 다시 삽입하는 것이 아니라

토론 #4

To solve this, you just need to manually re-execute your script tags on popstate.

What @chanind sad is 100% true. I did some testing with pattern similar to this in defunkt/jquery-pjax#235 and got strange results on 1.8/1.9, but this here could maybe fix inline scripts initalization on back button. will do some test...

토론 #5

Nice! Thanks i had the same issue. The inline script tag was executed in normal or pjax request but never on pushstate/popstate request... i dont know why..

Many thanks @chanind :)

토론 #6

I bumped into a wierd situation that my inline scripts were executed twice during popstate.

It turns out that on popstate, the page contents may have been fetched via ajax. This happens after a manual refresh or a pjax timeout, which refreshes the page and clears the pjax state cache. Whenever the page contents are fetched by ajax, pjax would executes inline scripts by itself, even during popstate.

I managed to handle the situation by extending @chanind 's snippet a bit. This should prevent the inline scripts from being executed twice:

$(document).on('pjax:popstate', function() {
    var isContentFromCache = true;
    $(document).one('pjax:complete.popstate-handling', function(){
        // Content loaded from ajax
        isContentFromCache = false;
    });

    $(document).one('pjax:end', function(event) {
        if(!isContentFromCache){
            // Inline scripts already executed by pjax.
            return;
        } else {
            $(event.target).find('script').each(function() {
                $.globalEval(this.text || this.textContent || this.innerHTML || '');
            });
            $(document).off('.popstate-handling'); // Cleanup the callback that's not fired
        }
    });
});
따라서 서로 상쇄되는 두 가지 이벤트 처리 절차로 더욱 간소화할 수 있다.
$(document).on('pjax:popstate', function() {
    $(document).on('pjax:complete.popstate-handling', function(){
        // Content loaded from ajax, prevent pjax:end.popstate-handling from its execution
        $(document).off('.popstate-handling');
    });

    $(document).on('pjax:end.popstate-handling', function(event) {
        // Manually execute the inline scripts
        $(event.target).find('script').each(function() {
            $.globalEval(this.text || this.textContent || this.innerHTML || '');
        });
        $(document).off('.popstate-handling'); // Cleanup the callback that's not fired
    });
});
이 모든 것을 한 후에 나는 처음부터 내연 스크립트를 피해야 한다고 생각한다: P

좋은 웹페이지 즐겨찾기