Upgrade to Pro — share decks privately, control downloads, hide ads and more …

PushState or Bust

PushState or Bust

There's only one sane way to make use of pushState. This presentation explains which way that is and why its the only real choice.

danwrong

April 25, 2012
Tweet

More Decks by danwrong

Other Decks in Programming

Transcript

  1. Why? ‣ Do snazzy transitions between pages ‣ Your client-side

    MVC app gives you no choice ‣ Reduce amount of bytes over the wire ‣ Reduce burden on the server
  2. Breaking the web ‣ The back button ‣ Bookmarking and

    link sharing ‣ Search engine crawling ‣ Redirects, 404 and other HTTP level stuff ‣ Works (at least minimally) across browsers
  3. // Link to fragment identifier <a href="#!/danwrong">@danwrong</a> // Listen for

    change, do change state window.addEventListener('hashchange', function() { var path = location.hash.replace(/^#!/, ''); $.get(path, function(state) { render(state); }); });
  4. Have we killed the web? ‣ The back button ‣

    Bookmarking and link sharing ‣ Search engine crawling ‣ Redirects, 404 and other HTTP level stuff ‣ Works (at least minimally) across browsers Meh. Meh. Meh.
  5. // fetch new state $.get('/danwrong', function(state) { history.pushState(state, "Twitter /

    danwrong", "/danwrong"); render(state); } // Handle back / forward button window.addEventListener('popstate', function(e) { render(e.state); });
  6. Have we killed the web? ‣ The back button ‣

    Bookmarking and link sharing ‣ Search engine crawling ‣ Redirects, 404 and other HTTP level stuff ‣ Works (at least minimally) across browsers Meh.
  7. Have we killed the web? ‣ The back button ‣

    Bookmarking and link sharing ‣ Search engine crawling ‣ Redirects, 404 and other HTTP level stuff ‣ Works (at least minimally) across browsers
  8. <a href="/mentions" class="ps">Mentions</a> if (history.pushState) { document.addEventListener('click', function(e) { if

    (e.target.className == 'ps') { $.get(e.target.href, function(state) { render(state); history.pushState(state, state.title, e.target.href); }); e.preventDefault(); } }); }
  9. class ConnectController def mentions @mentions = get_mentions if request.xhr? render

    :json => { :title => 'Twitter / mentions', :section => 'connect', # render just the page content but not the global "chrome" :page_html => MentionsView.new(@mentions).render } end # otherwise render the whole page as normal end end
  10. Have we killed the web? ‣ The back button ‣

    Bookmarking and link sharing ‣ Search engine crawling ‣ Redirects, 404 and other HTTP level stuff ‣ Works (at least minimally) across browsers