代码之家  ›  专栏  ›  技术社区  ›  Phil

处理AJAX加载内容的浏览器历史记录

  •  0
  • Phil  · 技术社区  · 7 年前

    我有一个页面,左边是导航链接,右边是内容分区。导航链接HTML是这样设置的。

    <a href="javascript:;" class="nav-link" data-mode="myModeValue">Test</a>
    

    我已经设置了一个JavaScript函数,如下所示,我认为该函数将绑定到链接,将新状态推送到浏览器历史记录中,并根据数据模式值加载该链接的内容。前进可以很好地工作,但是当我后退时,有时我必须单击后退两次才能返回到上一个哈希,我不知道为什么。

    <script language="javascript">
        // Create var indicating the CURRENT mode we're on - home being the default when page loads
        currentMode = "home"; 
        // Push the default page (mode) into the history
        history.pushState(null, document.title, location.pathname + "#!/detail-mode/" + currentMode);
    
        // bind to my nav links
        $(document).on('click', '.nav-link', function(e){
            e.preventDefault();
            ajaxLoadVehicleSearchDetailContent($(this).data('mode'));
        });
    
        function ajaxLoadVehicleSearchDetailContent(mode) {
            // Get the mode and link object
            var thisMode = mode.toString().toLowerCase();
            var thisLink = $('a[data-mode="' + mode + '"]');
            // If we're switching to a different tab - continue
            if (currentMode != thisMode) {
                currentMode = thisMode;     
                // Get the content via AJAX
                $.ajax({
                    url: "/myAjaxFunctionFileURL",
                    type: "POST",
                    data: { method:"getTabContent", mode:thisMode },
                    success: function(result) {
                        history.pushState(null, document.title, location.pathname + "#!/detail-mode/" + thisMode);
                        // Update the content area - fadeOut,replace,fadeIn
                        $('#contentArea').fadeOut(globalAnimationDuration, function() {
                            $('#contentArea').html(result).fadeIn(globalAnimationDuration);
                            $('.nav-link').removeClass('current');  
                            thisLink.addClass('current');                   
                        });
                    }
                });     
            }
        }
    
        // Listen for the popstate and load correct content when user goes BACK in history
        window.addEventListener("popstate", function() {
            if (location.hash.indexOf("#!") != -1) {
                var thisMode = location.hash.split("/").slice(-1)[0];           
                ajaxLoadVehicleSearchDetailContent(thisMode);           
            }
        }, false);
    </script>
    

    这个 globalAnimationDuration var只是一个值为500的变量。

    JSFiddle Here

    非常感谢。

    1 回复  |  直到 7 年前
        1
  •  0
  •   Sandy Gifford    7 年前

    我想出来了。既然我也这么叫 ajaxLoadVehicleSearchDetailContent 在前向和后向导航中,单击后退时会错误地将项目添加到堆栈中。因此,它将从堆栈中弹出项目,调用函数,然后将其重新添加到堆栈中,除非它是当前选项卡。

    我的解决方案为我的 ajaxLoadVehicleSearchDetailContent() 方法如下所示。

    function ajaxLoadVehicleSearchDetailContent(mode,backward) {
            // Get the mode and link object
            var thisMode = mode.toString().toLowerCase();
            var thisLink = $('a[data-mode="' + mode + '"]');
            // If we're switching to a different tab - continue
            if (currentMode != thisMode) {
                currentMode = thisMode;     
                // Get the content via AJAX
                $.ajax({
                    url: "/myAjaxFunctionFileURL",
                    type: "POST",
                    data: { method:"getTabContent", mode:thisMode },
                    success: function(result) {
                        if (!backward) history.pushState(null, document.title, location.pathname + "#!/detail-mode/" + thisMode);
                        // Update the content area - fadeOut,replace,fadeIn
                        $('#contentArea').fadeOut(globalAnimationDuration, function() {
                            $('#contentArea').html(result).fadeIn(globalAnimationDuration);
                            $('.nav-link').removeClass('current');  
                            thisLink.addClass('current');                   
                        });
                    }
                });     
            }
        }
    

    然后,当我从nav链接调用它时-send false,当我从popstate事件调用它时,我调用true。