I've been investigating a few of the JavaScript frameworks such as Backbone.js and Batman.js for a while and whilst I really like them, I have one niggling thing that I keep coming back to. That issue is accessibility.
As a web developer I've always tried to make my websites and applications with accessibility in mind, especially using the idea of progressive enhancement.
Clearly out of the box these new JS frameworks don't gracefully degrade, so I was wondering what are other developers thoughts on this issue and what are you doing about it. After all the accessibility of a website / app isn't really an optional thing as it's part of the law in many countries.
Maybe I'm just being overly zealous on this subject, and not appreciating how far things have come in terms of accessibility.
I use a js-framework (spine.js in my case) in my latest site. Still I make sure that non-js browsers (certainly not over zealous: think SEO) can navigate my site and digest the contents.
As an example I'm going with a search-page with products being shown. Products can be paged, filtered, sorted. Of course this is an example of the generalized idea.
PREREQ: use a template-engine that can both render server-side and client-side. (I use Mustache) . This makes sure you can render models without js- through server-side templating, and render models with js through client-side templating.
Initially: render the products using server-side mustache-template. Also include a 'bootstrapJSON'-object which contains the same products in JSON-format.
Initially: all links (product-detail page, paging, sorting, filtering) are real server-side urls (no hashbang urls)
The end-result is a page which can be navigated 100% with paging, sorting, filtering without the use of JS.
all paging,sorting, filtering urls result in a request to the server, which in turn results in a new set of products being rendered. Nothing special here.
JS-enabled - on domload:
now every (filtering, paging, sorting ) url should result in a client-side state-change, which would probably result in your js-framework doing an ajax-request to the server to return new products (in JSON-format) . Rerendering this again on the client should result in your updated view.
The logic part of the code to handle the ajax-request in 6. on the server-side is 100% identical to the code used in 4. Differentiate between an ajax-call and an ordinary request and spit out the products in JSON or html (using mustache server-side) respectively.
EDIT: UPDTATE JAN 2013 Since this question/answer is getting some reasonable traction I thought I'd share some closely-related aha-moments of the last year:
Spitting out JSON and rendering it client-side with your client-side mvc of choice (steps 6. and 7. above) can be pretty costly cpu-wise. This, of course, is especially apparent on mobile-devices.
I've done some testing to return html-snippets on ajax (using server-side mustache-template rendering) instead of doing the same on the client-side as suggested in my answer above. Depending on your client-device it can be up to 10 times faster (1000ms -> 100ms) , of course your mileage may vary. (practically no code changes needed, since step 7. could already do both)
Of course, when no JSON is returned there's no way for a client-side MVC to build models, manage events, etc. So why keep a clientside MVC at all? To be honest, with even very complex searchpages in hindsight I don't have much use for client-side mvc's at all. The only real benefit to me is that they help to clearly separate out logic on the client, but you should already be doing that on your own imho. Consequently, stripping out client-side MVC is on the todo.
Oh yeah, I traded in Mustache with Hogan (same syntax, a bit more functionality, but most of all extremely performant!) Was able to do so because I switched the backend from java to Node.js (which rocks imho)