0

我正在使用 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>
4

1 回答 1

0

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

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

  1. 当您的页面加载时,您会查看 History.getState().data。如果您在那里识别出您的一个状态,那么这意味着您正在从另一个页面导航回您的页面,例如从您访问的外部链接。(注意:浏览器可能刚刚从缓存加载了您的页面,或者它可能已经从服务器重新加载。应该没关系,因为您将使用刚刚找到的状态更新页面/ui)。因此,将您的页面更新到该状态。如果您不认识 state,那么就您的页面而言,这是第一次加载。适当地初始化。
  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>
于 2013-11-01T17:02:06.807 回答