2012-08-17 17 views
8

Ho la seguente applicazione di test: http://dev.driz.co.uk/ajax/Utilizzando i pulsanti Indietro e Avanti con l'API Storia

È possibile fare clic sul link per caricare in altre pagine utilizzando jQuery AJAX e ci sono due tipi, globalTabs e localTabs che carico contenuto in diversi pannelli. NOTA: che ogni pagina è in realtà la pagina intera, ma prendiamo il contenuto che vogliamo usando il metodo di ricerca di jQuery.

Per migliorare questo sto utilizzando l'API di cronologia HTML5 (History.js per il cross-browser).

I titoli e gli URL cambiano correttamente e lo stack della cronologia viene inviato correttamente e quando si utilizzano i pulsanti Indietro e Avanti l'url e il titolo vengono ripristinati.

Ora la parte complicata sta caricando nuovamente il contenuto dallo stato precedente e più complicato caricando il tipo corretto ad es. ajax globale o locale. Per raggiungere questo obiettivo, ho bisogno di passare ENTRAMBI i dati e il tipo allo stato push in modo che possa essere riutilizzato nuovamente per il popstate ...

Qualcuno può aiutarmi a indicarmi la giusta direzione? Ho tutte le prime parti funzionanti, solo un caso di ottenere questo passaggio del tipo Ajax al pushState e quindi riutilizzarlo con la modifica del popstate.

di migliorare su questo ho riscriverlo come segue per indicare il mio piano per far passare il tipo e di dati:

NOTA: la Storia maiuscola è perché sto utilizzando History.js

var App = { 

    init: function() { 

     $(document).ready(function() { 

      $('.globalTabs li a').live('click', function (e) { 
       e.preventDefault(); 
       App.globalLoad($(this).attr('href')); 
      }); 

      $('.localTabs li a').live('click', function (e) { 
       e.preventDefault(); 
       App.localLoad($(this).attr('href')); 
      }); 

     }); 

     window.addEventListener('popstate', function(event) { 

      // Load correct content and call correct ajax request... 

     }); 

    }, 

    localLoad: function (url) { 

     $.ajax({ 
      url: url, 
      success: function (responseHtml) { 
       $('.localContent').html($(responseHtml).find('#localHtml')); 

       $data = { $(responseHtml).find('#localHtml'), 'local'}; 

       History.pushState($data, $(responseHtml).filter('title').text(), url); 
      } 
     }); 

    }, 

    globalLoad: function (url) { 

     $.ajax({ 
      url: url, 
      success: function (responseHtml) { 
       $('.mainContent').html($(responseHtml).find('#globalHtml')); 

       $data = { $(responseHtml).find('#globalHtml'), 'global'}; 

       History.pushState($data, $(responseHtml).filter('title').text(), url); 
      } 
     }); 

    } 

}; 

App.init(); 

AGGIORNAMENTO: Per chiarire questa domanda, sono due problemi con cui cerco aiuto.

1.) Ottenere i pulsanti Indietro e Avanti che funzionano con le richieste Ajax in modo che possano caricare nuovamente i dati corretti nell'area del contenuto.

2.) Caricamento del contenuto nell'area corretta passando anche il contenuto con il metodo pushState in modo che sappia se si tratta di una div div o di una richiesta di divisione locale.

risposta

12

l'oggetto dati è errato, è per questo che si ottiene il problema. Un oggetto è definito da chiave, valori coppia:

object = {key:'value'}; 
$data = { text:$(responseHtml).find('#globalHtml'), type:'global', url:'the_url'}; 

non

$data = { $(responseHtml).find('#globalHtml'), 'global'}; 

Utilizzando la definizione dell'oggetto otterrete i vostri dati utilizzando Storia.getState()

History.Adapter.bind(window,'statechange',function(){ 
    var data = History.getState().data; 
    if(data){ 
     var html = data.text; 
     var type = data.type; 
     var type = data.url; 
     if(html && type){ 
      if(type == 'global'){ 
       // just change html 
       $('.mainContent').html(html); 
       // call the App object's function 
       if(url) App.localLoad(url); 
      }else{ 
       $('.localContent').html(html); 
      } 
     } 
    } 
}) 

NOTA:

  • quando stateChange evento ottenere licenziato se sono presenti dei dati che scatterà l'ajax chiama
  • per simulare la chiamata AJAX senza farlo basta cambiare il titolo anche , penso che lo copre

EDIT

  • l'oggetto di dati è in realtà tratto da History.getState(). I dati non History.getState()
  • aggiunto un altro param all'oggetto conservato per preservare url
  • utilizzando l'URL e il tipo è possibile effettuare una chiamata a la stessa funzione in caso onClick

PROBLEMA:

Uncaught TypeError: Converting circular structure to JSON

Un oggetto fa riferimento a se stesso qualche; da qui il messaggio "struttura circolare". Ciò significa che stai cercando di stringificare un oggetto che ha un riferimento a se stesso, questo normalmente accade con gli elementi DOM. Si dovrebbe davvero pensare di cambiare

$data = { $(responseHtml).find('#localHtml'), 'local'}; 

a:

$data = { html:$(responseHtml).find('#localHtml').html(), type:'local'}; 

Avviso le chiavi per l'oggetto (html e tipo) e la chiamata di funzione HTML (.html()), in questo modo è solito inviare inutili dati, solo l'html. Se è necessario utilizzare i dati HTML quando si carica come un oggetto DOM basta usare questo:

var DOM_Element_loaded = $('<div>').html(html_loaded); 

ora è possibile utilizzare per cercare DOM_Element_loaded/manipolare i dati in html caricato senza la necessità di collegarlo al corpo.

+0

E come faccio a spegnerlo? Non parli di Popstate? Come quello che devo fare è cambiare il contenuto e poi il titolo (replicando efficacemente ESATTAMENTE quello che ha fatto la chiamata ajax) quando un utente usa i pulsanti Indietro e Avanti, ma invece di ajax userà i dati della cronologia come nessun punto che lo ricarica indietro in ovviamente. – Cameron

+0

Ho anche ricevuto l'errore: 'Uncaught TypeError: conversione della struttura circolare in JSON 'Qualche idea cosa c'è che non va? http://dev.driz.co.uk/ajax/ – Cameron

+0

modificato la mia risposta, riguardo l'errore json, basta controllare di passare oggetti semplici, senza funzioni – cuzzea

0

NOTA: questo è davvero più un commento che una risposta, ma si ottiene una migliore evidenziazione della sintassi con risposte di risposta.

Questo è quello che ho fatto quando mi sono imbattuto in questo problema. Se ricordo bene, questo ha impedito il problema della doppia richiesta.

window.onpopstate = function(event) { 
    if (event.state && event.state.initialHref) { 
    // make an AJAX request 
    // URL for AJAX request is event.state.initialHref 
    } 
} 

Quando uso history.pushState()/history.replaceState(), sto definendo un initialHref proprietà nell'oggetto per il 1 ° argomento. Sto usando un URL assoluto per questo valore, non uno relativo.

Problemi correlati