Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/370.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript .back,and.pushState-两部历史的故事_Javascript_Html_History - Fatal编程技术网

Javascript .back,and.pushState-两部历史的故事

Javascript .back,and.pushState-两部历史的故事,javascript,html,history,Javascript,Html,History,这不是一个问题,而是一个有趣问题的发现。这也是一种“从失败中学习” 我正在尝试为IE的HTML5历史记录编写单元测试(使用window.hash替代状态维护)。duckpunch按预期工作,在用户测试期间,我在IE、Chrome和Firefox中得到了一致的结果 问题出在单元测试上。在它们中,我对history.pushState()、.replaceState、.back()和.forward()进行了各种组合。这些在Firefox和IE中运行良好,但Chrome给了我完全不一致的结果。下面的

这不是一个问题,而是一个有趣问题的发现。这也是一种“从失败中学习”

我正在尝试为IE的HTML5历史记录编写单元测试(使用window.hash替代状态维护)。duckpunch按预期工作,在用户测试期间,我在IE、Chrome和Firefox中得到了一致的结果


问题出在单元测试上。在它们中,我对history.pushState()、.replaceState、.back()和.forward()进行了各种组合。这些在Firefox和IE中运行良好,但Chrome给了我完全不一致的结果。下面的答案解释了原因。

考虑以下几点:

var originalPath = window.location.pathname.toString();
history.pushState({ value: 'Foo' }, '', 'state-1');
history.pushState({ value: 'Bar' }, '', 'state-2');

history.pushState({ value: 'Baz' }, '', 'state-3');
history.back();
history.back();
console.log(history.state.value);
//So we can hit refresh and see the results again...
setTimeout(function () {
    history.replaceState(null, '', originalPath);
}, 250);
有人会期望这段代码返回“Foo”——在Firefox和我的IE duck punch中,这正是它所做的——但在Chrome中,它的响应是“Baz”

经过一些调查,我解决了这个问题:IE和Firefox同步更新历史记录,如果需要加载任何页面,那么就进行异步更新。Chrome似乎立即变得异步

证据:

window.onpopstate = function () {
    console.log('ping');
}
history.pushState({ value: 'Foo' }, '', 'state-1');
history.back();
console.log('pong');
在Firefox中,它返回“ping”pong'-表示事件作为history.back()调用的一部分被调度。在Chrome中,它返回“pong”ping’-表示事件被放置在队列中进行调度

如果不使用此事件分派模型来管理历史记录和位置对象的状态,这将不会太糟糕,但显然是这样

window.onpopstate = function () {
    console.log('Event...', history.state, window.location.pathname.toString());
}
history.pushState({ value: 'Foo' }, '', 'state-1');
history.back();
console.log('Inline...', history.state, window.location.pathname.toString());

这是一个有趣的怪癖,需要使用jQuery延迟链来正确处理我的单元测试。我对此并不特别高兴,但你能做些什么呢

为了在单元测试中处理异步返回事件,我使用和。这是一个更新历史事件中的计数器以跟踪chrome何时处理事件以及Jasmine的异步支持以阻止单元测试的案例,直到我们看到事件更改:

递增计数器:

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

    // Increment the counter
    window.historyEventCounter++;

});
Jasmine异步单元测试。等待将被阻止,直到历史事件发生:

describe('back navigation', function () {
    it('should change url', function () {

        var initialHistoryEventCount;

        // Cache the initial count

        runs(function() {
            initialHistoryEventCount = window.historyEventCounter;
            History.back();
        });

        // Block until the event counter changes

        waitsFor(function() {
            return (initialHistoryEventCount !== app.historyEventCounter);
        }, "The page should be navigated back", 1000);

        // Now confirm the expected back behaviour. Event failures will time-out.

        runs(function() {
            expect(window.location.href).toEqual("http:// my back url");

            // ... more tests about the page state
        });
    }
}