【问题标题】:Should the window.statechange be triggered when I navigate back from an external link?当我从外部链接返回时是否应该触发 window.statechange?
【发布时间】:2013-10-31 16:39:34
【问题描述】:

我正在使用 History.js(jquery.history.js v1.8b2)。 Chrome 版本 30.0.1599.101 m.

我不知道如何让 History.js 以我期望的方式工作。

我有一个包含两个链接的页面。第一个模拟ajax 操作。它只是将页面中<h2> 中的文本从“开始”更改为“2”。第二个链接只是指向 google.com。

这是我的工作:

  • 在 chrome 中清除缓存
  • 加载页面
  • 单击第一个链接(我调用 pushState,发生 statechange,然后我将文本更新为“2”)
  • 点击 google.com 链接(转到 google)
  • 单击浏览器的返回按钮。

单击后退按钮后,我希望调用 statechange 处理程序,然后我会获取我的状态对象,以便将文本恢复为“2”。

但是处理程序没有被调用。所以我的页面留下了文本“开始”(浏览器中的缓存页面)。有趣的是,该 url 设置为我在 pushState 调用中推送的“2”版本。

我错过了什么吗?这是我的代码:

<h2 id="state">start</h2>

<a id="2" class="button" href="#">Goto State 2</a>

<a href="http://google.com">Goto google</a>

<script type="text/javascript">

    $(function() {

        History.Adapter.bind(window, "statechange", function() {
            console.log("statechange called");

            var state = History.getState();

            if (state.data.mystate) {
                // Restore the old state
                $("#state").text(state.data.mystate);
            } else {
                // Start state
                $("#state").text("start");
            }
        });


        $(".button").click(function(e) {
            // push the state we're transitioning to
            var newState = $(this).attr("id");

            History.pushState(
                { mystate: newState },
                "at state " + newState,
                "http://localhost:50494/PushState?state=" + newState);

            // statechange will be called now, and we'll update the page from our newState

            e.preventDefault();
        });


    });

</script>

【问题讨论】:

    标签: html history.js


    【解决方案1】:

    我认为答案是否定的,从页面外返回时不应该调用 statechange。

    我注意到http://browserstate.github.com/history.js/demo/ 的演示按我的预期工作,所以我做了一个查看源代码来看看它是如何工作的。据我所知,这就是你应该如何使用 History.js。

    1. 当您的页面加载时,您会查看 History.getState().data。 如果您在那里识别出您所在的某个州,则意味着您正在从另一个页面导航回您的页面,例如从您访问的外部链接。 (注意:浏览器可能刚刚从缓存中加载了您的页面,或者它可能已经从服务器重新加载。没关系,因为您将使用刚刚找到的状态更新页面/ui)。因此,将您的页面更新到该状态。 如果您不认识该状态,那么就您的页面而言,这是第一次加载。适当初始化。
    2. statechange 事件将在您页面内的“ajax”状态之间的浏览器后退/前进按钮上调用(您在这一页中推送的状态)。 当你调用 pushState() 时它也会被调用。呵呵,是不是很迷惑?是的,所以当您想在页面中转换到新状态时,请遵循以下模式:
    3. 准备您的状态对象(可能涉及 ajax 调用),
    4. 致电pushState(yourObject,...)
    5. 暂时不要更新您的页面/用户界面。
    6. 您实际上是从稍后会被调用的 statechanged 处理程序更新您的页面/用户界面。

    我错误地认为您应该完成更新页面的所有工作,然后再推送状态。这只会让事情变得困难,因为 statechanged 也会被调用。

    此外,一般来说,您应该在当前页面内推送类似 ajax 的转换状态。不要为您在页面外关注的链接推送状态(除非您真的了解所有这些并且正在尝试做一些花哨的事情)。

    我已在此处更新了示例代码,以展示现在对我有用的内容:

    <h2 id="state">start</h2>
    
    <a id="2" class="button" href="#">Goto State 2</a>
    
    <a href="http://google.com">Goto google</a>
    
    
    <script type="text/javascript">
    
        $(function () {
            // page loading, check for available state I recognize
            var availableState = History.getState();
    
            if (!availableState.data.mystate) {
                // loading for the first time
                $("#state").text("start");
            } else {
                // load from the available state
                loadState(availableState);
            }
    
            History.Adapter.bind(window, "statechange", function () {
                var state = History.getState();
                loadState(state);
            });
    
            function loadState(state) {
                if (state.data.mystate) {
                    // update the page to this state
                    $("#state").text(state.data.mystate);
                } else {
                    // update the page to the initial state
                    $("#state").text("start");
                }
            }
    
    
            $(".button").click(function (e) {
                // The user clicked a button, so we want to transition to a new state
                // in this page. Push the state we're transitioning to (which we've hidden
                // in the id attribute in this example).
                var newState = $(this).attr("id");
    
                History.pushState(
                    { mystate: newState },
                    "at state " + newState, // title
                    "?state=" + newState);  // url
    
                // statechange will be called now, and we'll update the page from our newState
    
                e.preventDefault();
            });
    
    
        });
    
    </script>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-12-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-27
      • 2016-03-19
      • 2014-02-20
      相关资源
      最近更新 更多