为 AJAX 加载的内容操纵浏览器历史记录

Manipulating Browser History for AJAX loaded content

我有一个页面,左侧是导航 link,右侧是内容 div。导航links HTML是这样设置的。

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

我已经设置了一个 JavaScript 函数,如下所示,我认为它会绑定到 links,将新状态推送到浏览器历史记录并加载该 [=34] 的内容=] 基于数据模式值。前进非常有效,但是当我向后退时,有时我必须单击两次才能返回到以前的哈希值,我不确定为什么。

这是我目前的情况。

<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

谢谢!

我明白了。由于我在向前和向后导航中调用相同的 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');                   
                    });
                }
            });     
        }
    }

然后当我从我的导航中调用它时 link - 发送 false,当我从我的 popstate 事件中调用它时我调用 true。