2012-07-11 3 views
4

이것은 많은 질문이 아니지만 재미있는 문제로 인해 발견되었습니다. 또한 일종의 "내 실패로부터 배우기".back 및 .pushState - 두 개의 히스토리 이야기

IE (상태 유지를위한 대체품으로 window.hash 사용)에 대한 HTML5 기록 오리 펀치에 대한 단위 테스트를 작성하려고합니다. duckpunch는 예상대로 작동하며 사용자 테스트 중에 IE, Chrome 및 Firefox에서 일관된 결과를 얻습니다.

여기서 문제는 단위 테스트입니다. 그 (것)들에서 나는 history.pushState(), .replaceState, .back() 및 .forward()의 다양한 조합을한다. Firefox와 IE에서는 정상적으로 작동하지만 Chrome은 일관성없는 결과를 제공합니다. 아래 답변은 이유를 설명합니다.

답변

2

단위 테스트에서 비동기 백 이벤트를 처리하기 위해 HistoryJSJasmine을 사용했습니다.

증분 카운터 :

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

    // Increment the counter 
    window.historyEventCounter++; 

}); 

은 크롬 우리는 이벤트의 변화를 볼 때까지 부 시험을 차단하는 이벤트와 쟈스민의 비동기 지원을 처리 할 때 추적 이력 이벤트 카운터를 갱신하는 경우였다 재스민 비동기 유닛 테스트. waitsFor는 기록 이벤트가 발생할 때까지 차단됩니다.

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 
     }); 
    } 
} 
8

는 다음과 같은 고려 : - 파이어 폭스 내 IE 오리 펀치 모두에서이 그것을 수행 정확히 무엇인가 -

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); 

하나는 '푸'를 반환하는 코드의 덩어리를 기대를하지만, 크롬, 그것은 'Baz'로 응답합니다.

몇 가지 조사를 한 후에 문제를 해결했습니다. IE와 Firefox는 기록을 동 기적으로 업데이트 한 다음 페이지로드가 필요한 경우 비동기로 이동합니다. Chrome은 즉시 비동기로 표시됩니다.

증거 : 파이어 폭스에서

window.onpopstate = function() { 
    console.log('ping'); 
} 
history.pushState({ value: 'Foo' }, '', 'state-1'); 
history.back(); 
console.log('pong'); 

이 반환 '핑'; '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를 이연 체인의 사용을 필요로 하나. 나는 그것에 대해 특별히 행복하지 않지만 무엇을 할 수 있습니까?

관련 문제