内容通过 ajax 加载到 div,散列附加到 url,但无法添加历史记录和书签状态

content loads in div via ajax, hash appended to url, but can't add history and bookmark state

我很惭愧地说我花了多少时间为此苦苦挣扎,尝试了在这里和其他地方找到的各种方法,我迫切需要一点帮助。这就是我所在的位置:我有一系列交互式 SVG 图表,其中包含各种 links(到 WP posts),每个都分配了 post-link class。单击时,任何 linked post 的内容通过 ajax 成功加载到图表下方的 div 中,并且哈希片段附加到 URL .目前一切顺利。

但我无法设法以允许浏览器后退按钮功能的方式创建和捕获历史记录或捕获页面的 'ajaxed' 状态以允许书签或 link 共享。

我已经研究过使用 pushState、replaceState 和 popstate 获取浏览器历史记录,认为这将是解决方案,但我尝试过的都没有奏效。所以我删除了那些不正确的位置并提供了下面的基本代码,寻求一些指导来获得标题、后退按钮和书签功能。下面的代码包含在更大的文档就绪函数中:

//AJAX LOAD SINGLE POST CONTENT ON PAGE
$(function(){

    //enable accordion to function within ajaxed content
    $.ajaxSetup({
        cache:false,
        complete: function() {
            var cpicons = {
                header: "iconClosed",
                activeHeader: "iconOpen"
            };
            $(".accordion").accordion({
                header: "h3",
                collapsible: true,
                heightStyle: "content",
                navigation: true,
                icons:cpicons
            });
            $(".accordion-allclosed").accordion({
                header: "h3",
                collapsible: true,
                active: true,
                heightStyle: "content",
                navigation: true ,
                icons: cpicons
            });
        }
    });

    $(".post-link").click(function(e) {
        var toLoad = $(this).attr("href")+"#single-jobtype-post-container";         

        //capture slug from post url to use as hash
        var slug = $(this).attr("href").match(/[^/]*(?=(\/)?$)/)[0];
        window.location.hash = slug;
        //insert spinner followed by post's content 
        $("#single-jobtype-post-container").html("<div class='loading d-all t-all m-all'><i class='fas fa-spinner fa-spin fa-3x'></i></div>");
        $("#single-jobtype-post-container").load(toLoad);

        e.preventDefault();             
    });     

});

---更新---

正如下面 Kamil 所建议的,我改变了我的方法,让 URL 通过 hashchange 事件驱动 JavaScript。简单多了,问题解决了,吸取了教训!这是我的工作代码:

        $(function() {

        $("#exploration-grid a").click(function(e) {
            window.location.hash = $(this).attr("id");
            e.preventDefault();

            //set the "active" class as appropriate
            $('#exploration-grid a').removeClass('active');
            $(this).addClass('active');  

        });

        $(window).bind("hashchange", function(){
            var newHash = window.location.hash.substring(1);
            var postURL = window.location.protocol + "//" + window.location.host + "/" + "jobtypes" + "/" + newHash;

            if (newHash) {

                $("#single-jobtype-post-container").html("<div class='loading d-all t-all m-all'><i class='fas fa-spinner fa-spin fa-3x'></i></div>");
                $("#single-jobtype-post-container").load(postURL);

                var hashval = newHash.replace(/-/g, " ");
                hashtitle = hashval.toUpperCase();
                document.title = document.title + " - " + hashtitle;

            };

        });

        $(window).trigger("hashchange");

    });

如何不在 ajax 之后更改哈希,而是先更改哈希,然后通过加载适当的内容来响应哈希更改?

考虑以下 post: How to implement a hash-key navigation?

post 的相关内容如下:

if ("onhashchange" in window) {  
  alert("The browser supports the hashchange event!");  
}  

function locationHashChanged() {  
  if (location.hash === "#somecoolfeature") {  
    somecoolfeature();  
  }  
}  

window.onhashchange = locationHashChanged

您需要将内容加载代码粘贴到 locationHashChanged 函数中,并根据哈希下载代码段。浏览器应自动跟踪其历史中的哈希值,您只需要为每个状态输入反动代码。

我曾在一个 ERP 网站上工作,该网站使用哈希导航来支持单页模型。当我开始网络开发时,这对我来说是相当酷的东西。

我不知道你为什么要做这样的流程,但如果你愿意,你可以试试这个脚本:

a.html

<!doctype html>
<html>
<head>
    <meta charset="utf-8"><!--needed to define charset if you want grab using load() correctly-->
</head>
<body>
<a class="post-link" href="http://localhost/gauz/b.html">try me (B)<a><br>
<a class="post-link" href="http://localhost/gauz/c.html">try me (C)<a><br>
<div id='single-jobtype-post-container'>I'm default for a.html</div>
<div class="share-link">share link: <span></span></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
$(function(){

    function getData(url, clicked=false){
        if(window.location.hash == ''){
            //capture slug from post url to use as hash
            var slug = url.match(/[^/]*(?=(\/)?$)/)[0];
            window.location.hash = slug.match(/[^/]*(?=(\/)?$)/)[0];
        }else{
            if(clicked) window.location.hash = url.match(/[^/]*(?=(\/)?$)/)[0];
            var a = url.split('/');
            a.splice(-1,1, window.location.hash.replace('#',''));
            var url = a.join('/');
        }

        //var toLoad = url+"#single-jobtype-post-container"; wrong, you need space here to just grab content inside id=single-jobtype-post-container
        var toLoad = url+" #single-jobtype-post-container"; //see the space?

        //set shared link
        $('.share-link').find('span').text(window.location.href);
        //insert spinner followed by post's content 
        $("#single-jobtype-post-container").html("loading");
        $("#single-jobtype-post-container").load(toLoad);
    }

    $(".post-link").click(function(e) {
        getData($(this).attr("href"), true);
        e.preventDefault();             
    });

    //first time load
    if(window.location.hash != '')  
        getData(window.location.href);

    //we need hashchange event to handle back and forward history button
    $(window).on('hashchange', function( e ) {
        getData(window.location.href);
    });
});
</script>
</body>
</html>

b.html(其他页面示例)

<!doctype html>
<html>
<head>
    <meta charset="utf-8">
</head>
<body>
<div id="a">I am b.html</div>
<div id="b">xxxxxx</div>
<div id="single-jobtype-post-container">I'm your target of B</div>
<div id="c">yyyyy</div>
</body>
</html>

c.html(另一个例子)

<!doctype html>
<html>
<head>
    <meta charset="utf-8">
</head>
<body>
<div id="a">I am c.html</div>
<div id="b">xxxxxx</div>
<div id="single-jobtype-post-container">I'm your target of C</div>
<div id="c">yyyyy</div>
</body>
</html>