Window.onpopstate它's已通过所有href链接激活

Window.onpopstate it's activated with all href links

本文关键字:href 链接 激活 已通过 onpopstate Window      更新时间:2023-09-26

我正在使用jQuery ajax实现分页,但要处理浏览器的历史记录,到目前为止效果良好,但几个小时前我意识到,如果我在页面的任何部分都有链接:

<a href="#">My link</a>

点击这个链接,会调用函数window.onpopstate,但我不知道为什么,我网站的所有a HREF都会发生这种情况。

这是我的函数,检测当前状态以调用特定函数,并按国家或搜索词或指定URL的参数加载数据。

window.onpopstate = function(event) {
    console.log(event);
    var section = $('#wrapper section').attr('id');
    if(event && event.state) {
        
        //State for Reviews pagination ?page=x
        if (event.state.type == 'pagination') {
            popStateShopPage(event.state);
        }
        //State for Reviews pagination by country ?country=MX&page=x
        if (event.state.type == 'country') {
            popStateShopPageCountry(event.state);
        }
        //State for Reviews pagination by search ?search=hello&page=x
        if (event.state.type == 'search') {
            popStateShopPageSearch(event.state);
        }
        
    } else {
        if (section == 'shop-page') {
            popStateShopPage(1);
        }
        history.pushState(null);
    }
}

我正在使用这些功能来推动状态:

history.pushState({type: 'pagination', page: number_page}, "", "?page="+number_page);
history.pushState({type: 'country', page: number_page, country: country}, "", "?country="+country+"&page="+number_page);
history.pushState({type: 'search', page: number_page, term: term}, "", "?search="+term+"&page="+number_page);

如MSDN Mozilla Network中所述:

1.当活动历史记录条目发生更改时,将触发popstate事件。如果正在激活的历史记录条目是通过调用创建的history.pushState()或受到对的调用的影响history.replaceState(),popstate事件的state属性包含历史条目的状态对象的副本。

2.请注意,仅调用history.pushState()或history.replaceState()不会触发popstate事件。popstate事件仅被触发通过执行浏览器操作,例如单击后退按钮(或在JavaScript中调用history.back())。

window.onposite触发的原因是,首先,当您单击锚点标记时,历史记录已经更改;其次,您正在执行浏览器操作。

在我看来,无法避免这种情况,正如JavaScritp《最终指南:》中所述

某些事件导致由执行关联的默认操作web浏览器。例如,当标记上发生单击事件时浏览器的默认操作是跟随超链接。默认操作只有在事件的所有三个阶段之后才执行类似的操作传播完成,以及在事件期间调用的任何处理程序传播有机会阻止默认操作通过调用Event对象的preventDefault()方法发生。

这三个阶段是:捕获、定位和冒泡。

希望它有用!

我建议检测popstate侦听器中的哈希标记:

addEventListener('popstate', (event) => {
            if (document.location.hash !== "") return;
            else doWhatEverYouWant();
        })

否则,如果使用防止默认,则必须再次处理历史推送。