javascript 如何使用history.js一次性捕获状态更改事件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7751263/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 01:10:35  来源:igfitidea点击:

how to catch a state change event ONCE with history.js?

javascriptajaxjavascript-eventsbrowser-historyhistory.js

提问by Alexander Morland

I have an example code below where if you click the links, then use back and forward, each state change will cause more and more hits on the 'statechange' event. Instead of the one that I expect.

我在下面有一个示例代码,如果您单击链接,然后使用后退和前进,每个状态更改都会导致越来越多的“statechange”事件点击。而不是我期望的那个。

Links:

链接:

Code:

代码:

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>History start</title>
</head>
<body>
    <h1>Headline</h1>
    <hr>
    <div id="menu">
        <ul>
            <li>
                <a href="page-1">Page 1</a>
                <div style="display:none;">
                    <h2>Page 1</h2>
                    <p>Content 1</p>
                </div>
            </li>
            <li>
                <a href="page-2">Page 2</a>
                <div style="display:none;">
                    <h2>Page 2</h2>
                    <p>Content 2</p>
                </div>
            </li>
        </ul>
    </div>
    <hr>
    <div id="content">
        <h2>Start page</h2>
        <p>Paragraf</p>
    </div>
    <script src="external/jquery-1.6.2.min.js"></script>
    <script>if ( typeof window.JSON === 'undefined' ) { console.log("Loaded json2"); document.write('<script src="external/json2.js"><\/script>'); }</script>
    <script src="external/history.adapter.jquery.js"></script>
    <script src="external/history.js"></script>
    <script>
    $(document).ready(function() {
        History.enabled = true;

        $('a').each(function() {
            $(this).click(function(e) {
                e.preventDefault();
                var $link = $(e.target),
                    state = {'href': $link.attr('href'), 'title': $link.html()},
                    $div = $link.siblings('div'),
                    content = $div.html();

                $('#content').html(content);

                History.pushState(state, state.title, state.href);

                return false;
            });
        });

        History.Adapter.bind(window, 'statechange', function() {
            var State = History.getState();
            // remove double hit on event
            console.log(State);

        });

    });
    </script>
</body>
</html>

回答by Jared

It's because you're calling the pushState function when you load the page, which also causes a statechange. I was in a similar situation and used a but a boolean before my pushStates so I knew I was doing a pushState. It looks like this...

这是因为您在加载页面时调用了 pushState 函数,这也会导致 statechange。我处于类似的情况,在 pushStates 之前使用了一个布尔值,所以我知道我在做一个 pushState。看起来像这样...

historyBool = true;
History.Adapter.bind(window,'statechange',function(){ // Note: We are using statechange instead of popstate

var State = History.getState(); // Note: We are using History.getState() instead of event.state

    //don't run our function when we do a pushState
    if(historyBool){
        historyBool = false;
        tempFunction = new Function(State.data.ajaxRunFunction);
        tempFunction();
    }
    historyBool = true;
});

historyBool = false;
historySet = {ajaxRunFunction: "upc('" + pageID + "','')"};
History.pushState(historySet,"","");

回答by lvanzyl

While not relevant to your specific problem, I had a scenario where I needed to unbind the event handler from the History Adapter. To do so you can unbind the "statechange" event from window, which is what History.Adapter binds to when you call History.Adapter.bind() :

虽然与您的具体问题无关,但我有一个场景,我需要从历史适配器中取消绑定事件处理程序。为此,您可以从窗口解除“statechange”事件的绑定,这是 History.Adapter 在您调用 History.Adapter.bind() 时绑定到的:

$(window).unbind('statechange.namespace');

You can added a namespace to the event to avoid unbinding other unrelated event handlers as above, or use a named function to unbind that function specifically. To use the above namespace, you would need to bind the handler using the same namespace, ie

您可以向事件添加命名空间,以避免解除绑定其他不相关的事件处理程序,或者使用命名函数专门解除绑定该函数。要使用上述命名空间,您需要使用相同的命名空间绑定处理程序,即

History.Adapter.bind(window,'statechange.namespace',function(){...}