停止在hashchange上触发popstate

时间:2014-09-03 00:30:03

标签: javascript html5-history

我正在使用History API并使用push和pop状态。我想在某些情况下停止popstate事件,我只将哈希附加到URL。例如,在某些情况下,点击锚点会将#附加到网址,并立即触发popstate)我想避免将##somehasvalue附加到网址的所有情况阻止popstate开火。我正在使用查询参数维护网址,我没有任何情况需要在网址中使用#触发popstate事件。

这是我的代码。

if (supportsHistoryApi()) {

    window.onpopstate = function (event) {
    var d = event.state || {state_param1: param1, state_param2: param2};                       
    var pathName = window.location.pathname,
        params   = window.location.search;

    loadData(event, pathName + params, d.state_param1, d.state_param2);

}

4 个答案:

答案 0 :(得分:8)

据我所知,你无法阻止popstate开火。

您可以做的是检查event.state对象。在散列更改时,这将为null。 所以我建议添加一个

if(event.state === null) {
   event.preventDefault();
   return false;
}

从一开始就到你的popstate事件处理程序。 我认为这是防止在哈希值发生变化时触发popstate处理代码的最佳方法,但我有兴趣知道是否还有其他解决方案。

答案 1 :(得分:0)

万一有人仍然需要这个:

var is_hashed = false;

$(window).on('hashchange', function() {
    is_hashed = true;
});

window.addEventListener('popstate', function(e){
    // if hashchange
    if (is_hashed) {
        e.preventDefault();
        // reset
        is_hashed = false;
        return false;
    }

    // Your code to handle popstate here
    ..................
});

答案 2 :(得分:0)

这很简单。

为防止在单击带有哈希的链接后触发popstate事件,您必须消除单击链接的后果-将哈希添加到浏览器地址栏中。

基本上,您必须为click事件创建处理程序,检查是否单击了您希望防止在URL中出现哈希值并通过在其中调用event.preventDefault();来防止哈希值出现的元素处理程序。

这是代码示例:

/**
 * This your existing `onpopstate` handler.
 */
window.onpopstate = function(e) {
    // You could want to prevent defaut behaviour for `popstate` event too.
    // e.preventDefault(); 
    // Your logic here to do things. 

    // The following reload is just an example of what you could want to make
    // in this event handler.
    window.location.reload();
};

/**
 * This is the `click` event handler that conditionally prevents the default
 * click behaviour.
 */
document.addEventListener('click', function(e) {
    // Here you check if the clicked element is that special link of yours.
    if (e.target.tagName === "A" && e.target.hash.indexOf('#the-link-i-want-make-discernable') > -1) {
        // The 'e.preventDefault()' is what prevent the hash to be added to
        // the URL and therefore prevents your 'popstate' handler to fire.
        e.preventDefault();
        processMySpecialLink(e, e.target);
    }

});

/**
 * Just an example of the link click processor in case you want making something
 * more on the link click (e.g. smooth scroll to the hash).
 */
function processMySpecialLink(e, target) {
    // Make things here you want at user clicking your discernable link.
}

以下是匹配的HTML标记:

<!-- Somewhere in the markup -->
<span id="the-link-i-want-make-discernable"></span>
<!-- Some markup -->
<a href="#the-link-i-want-make-discernable">My Special Link</a>
<!-- Another markup -->
<a href="#just-common-link">Any other link</a>

这一切都做上述操作:防止特殊哈希链接的默认行为。副作用是,在单击popstate哈希链接的特殊情况下,不会为URL添加任何哈希,因此不会触发#the-link-i-want-make-discernable事件。

答案 3 :(得分:0)

我有解决办法!

  • 在调用popstate事件时,请检查路径名是否已更改,或者只是哈希已更改。观看下面的内容对我的工作方式:
        window.pop_old = document.location.pathname;
        window.pop_new = '';
        window.onpopstate = function (event) {

            window.pop_new = document.location.pathname;

            if(pop_new != pop_old){

                //diferent path: not just the hash has changed

            } else {

                //same path: just diferent hash

            }

            window.pop_old = pop_new; //save for the next interaction

        };