2013-04-23 3 views
5

я использовал (https://github.com/browserstate/history.js) и есть кусок кода, как этотбраузера назад и вперед кнопка не вызывает метод обратного вызова с StateChange случае history.js

History.Adapter.bind(window, 'statechange', function() { 
    var State = History.getState(); 
    alert('Inside History.Adapter.bind: ' + State.data.myData); 
}); 

function manageHistory(url, data, uniqueId){ 
    var History = window.History; 
    if (!History.enabled) { return false; }   
    History.replaceState({myData: data}, null, '?stateHistory=' + uniqueId); 
} 

, если я призываю manageHistory() после моего AJAX вызова, то History.Adapter.bind метод обратного вызова вызывается правильно. Однако, если я нажму кнопку браузера, а затем нажмите кнопку переадресации, то приведет к навигации по страницам от B до A, затем A обратно к B, метод обратного вызова внутри History.Adapter.bind не вызывается. Это происходит как на хром, так и на IE9. Кто-нибудь знает, как исправить эту проблему, мне нужно получить State после браузера кликов, а затем переслать, чтобы обновить DOM. Пожалуйста, помогите

Примечание: Я использую версию 1.7.1 jquery.history.js для html4 браузера IE9

UPDATE (3 мая 2013): Поговорим немного о моем требовании

Sorry Я был занят другой задачей, что до сих пор мне иногда приходится смотреть на эту проблему. Итак, oncomplete вызова ajax, я взял ту информацию, которая вернулась ко мне, и вытолкнул ее в состояние. Мое требование: если я перемещаюсь со страницы А на страницу В, а затем на странице В, я выполняю число запросов ajax, которые приводят к манипуляции с DOM (позвольте каждому из запросов ajax, которые приводят к манипулированию DOM, state). Если я нажму кнопку «Назад», я вернусь на страницу А, и если я нажму кнопку «Вперед», я должен перейти на страницу В с последним состоянием, в котором я был.

Итак, моя мысль была, oncomplete моих ajax, я бы заменил последнее состояние в истории моим текущим состоянием (мой json-объект - это html, который я получаю обратно из запроса ajax). Если я использую состояние нажатия, скажем, я на странице B, и я нажимаю одну кнопку, моя страница теперь меняется на aaa, я нажимаюState aaa. Затем, если я нажму другую кнопку, моя страница теперь изменится на bbb, я нажимаюState bbb. Если я сейчас нажму кнопку «Назад», я все равно буду на странице B, с моим состоянием в History.Adapter.bind(window, 'statechange', function() {}) показать как aaa, если я снова нажму кнопку «Назад», я перейду на страницу А. Я не хочу этого поведения. Я хочу, чтобы, если я на странице B с состоянием bbb, и нажмите обратно, я перейду на страницу A, и если я нажму вперед, я перейду на страницу B с состоянием bbb. Надеюсь, это имеет смысл. Пожалуйста, помогите

+0

Re: Ваше обновление - Я думаю, что вы не хотите использовать историю, чтобы отслеживать «изменения состояния» в пределах страницы B/A. используйте историю использования вместе с изменением вашего URL-адреса. Любое изменение состояния в пределах одного URL-адреса (то есть A vs B) должно сохранять состояние другим механизмом (а не с помощью history.replaceState(); ... Это очень легко сделать с библиотекой MV *, например с базовой или угловой. – 1nfiniti

+0

jquery-mobile, у них есть ajaxy способ обработки страниц, которые могут вам пригодиться: http://jquerymobile.com/ – euxneks

ответ

3

Я вижу, что вы используете History.replaceState, которые удаляют последнее состояние истории в стеке и заменяют его на состояние, указанное в параметрах.

Я использую History.pushState на моем сайте и не сталкивается с такой проблемой, потому что эта функция не тянет последнее состояние, а добавляет новое состояние над ним. Это делает кнопки обратной перемотки вперед корректно.

Надеюсь, это вам поможет.

Edit: Используя пример change of select tag как listenner события:

function manageHistory(url, data, uniqueId){ 
    var History = window.History; 
    if (!History.enabled) { return false; }   
    History.replaceState({myData: data}, null, '?stateHistory=' + uniqueId); 
} 

$('select.select').change(function(e) { 

    e.preventDefault(); 

    // get url 
    // get data 
    // get uniqueId 

    manageHistory(url, data, uniqueId) 


}); 

History.Adapter.bind(window, 'statechange', function() { 
    var State = History.getState(); 
    // Launch the ajax call and update DOM using State.data.myData 
}); 
+0

вещь, с моим требованием, я не могу использовать pushState. Если я использую pushState, кнопка возврата вернется для каждого запроса ajax, но мое требование немного другое, я хочу сохранить последнее состояние. –

+0

Я думаю, что у нас не будет такого же понимания history.js. Я знаю, что кнопки браузера вернутся к ajax запросите, если вы History.Adapter.bind ajax-запрос с нажатием кнопки.Если вы хотите сохранить только последнее состояние, просто используйте pushState и ничего не свяжите. Прошу, я действительно новичок в этом. –

+0

Кроме того, я вижу, что вы говорите: если я invoke manageHistory() после моего aj ax call ... Я думаю, что вы должны выполнить свой вызов ajax внутри managehistory после нажатия состояния в стеке –

5

Что вам нужно сделать, это выглядит следующим образом:

  • Если страница, которую вы пришли это еще одна страница (например, вы открываете страницу B, а на предыдущей странице была страница A) вы делаете pushState.
  • Если, с другой стороны, предыдущая страница была той же страницей, на которой вы сейчас находитесь, просто выполните replaceState, заменив информацию информацией о вашем текущем состоянии.

(отслеживание предыдущей странице вам нужно будет сделать вручную в какой-либо переменной)

Это означает, что если вы идете от А до В (PushState) в новое состояние B (replaceState) , назад (переходит в состояние информации A) и следующий вперед (переходит в новое состояние B). Кроме того, если вы открываете A в первый раз, вам нужно сделать replaceState с информацией о состоянии A, чтобы A имел какое-то состояние (в противном случае он будет иметь пустой объект данных).

Возможно, было бы полезно посмотреть на мой номер this answer, в котором рассказывается о том, как вы построили упорядоченный стек истории с pushStates. Не совсем то, что вы хотите, конечно, но это немного проще написано и вместе с информацией в этом ответе должно получить вам поведение, которое вы хотите.

+0

@ Все, что меня ниспровергло ... было бы очень приятно узнать, почему, потому что я точно задал вопрос ... –

2

relpaceState всегда будет удалять состояние B.

Используйте pushState для состояний A и B.

И используйте replacestate для состояний aaa, bbb, ccc.

function manageHistoryBack(url, data, uniqueId){ 
    var History = window.History; 
    if (!History.enabled) { return false; }   
    History.replaceState({myData: data}, null, '?stateHistory=' + uniqueId); 


} 

function manageHistory(url, data, uniqueId){ 
    var History = window.History; 
    if (!History.enabled) { return false; }   
    History.pushState({myData: data}, null, '?stateHistory=' + uniqueId); 


} 

// Event listenner triggering aaa,bbb,ccc 
$('select.select').change(function(e) { 

    e.preventDefault(); 

    // get url 
    // get data 
    // get uniqueId 

    manageHistoryBack(url, data, uniqueId) 


}); 

// Event listenner triggering A, B 
$('select.select').change(function(e) { 

    e.preventDefault(); 

    // get url 
    // get data 
    // get uniqueId 

    manageHistory(url, data, uniqueId) 


}); 


History.Adapter.bind(window, 'statechange', function() { 
    var State = History.getState(); 
    // Launch the ajax call and update DOM using State.data.myData 
}); 

Успехов