Tout d'abord, je sais qu'il existe des bibliothèques qui fournissent des polyfills pour l' location.pushState
/ popState
( History.js , Hash.js , jQuery hashchange ), alors n'hésitez pas à les lier.
J'ai besoin d'une bibliothèque plus puissante pour réaliser ce qui suit dans un RIA:
<a>
sont exploités avec un gestionnaire de clics qui
preventDefault
) et location.pushState
place / définit location.hash pour les navigateurs plus anciens En outre, le contenu précédemment chargé devrait être restauré à mesure que l'utilisateur navigue vers l'arrière.
Par exemple, klick via Google+ dans Internet Explorer <10 et tout autre navigateur.
Y a-t-il quelque chose qui soit encore proche? J'ai besoin de support pour IE8, FF10, Safari 5 et Chrome 18. De plus, il devrait avoir une licence permissive comme MIT ou Apache.
Je crois que Sammy.js ( http://sammyjs.org ) (licence MIT) se concentre le mieux sur ce que vous voulez faire, ses 2 piliers principaux étant:
Je pourrais citer les documents, mais c'est plutôt simple:
Configurez les itinéraires de clients qui se rapportent à des choses à faire, par exemple: mettre à jour la vue via ajax
Relier les événements aux itinéraires d'appel, par exemple: appeler l'itinéraire ci-dessus lorsque je clique sur un lien. (Vous devriez vous assurer que e.preventDefault est appelé dans l'événement défini que je crois, car il s'agit vraiment d'une décision d'application, de sorte que toute bibliothèque que vous allez utiliser imho ne peut pas être extraite
Quelques documents pertinents
Exemple pour un itinéraire: (à partir de http://sammyjs.org/docs/tutorials/json_store_1 )
this.get('#/', function(context) { $.ajax({ url: 'data/items.json', dataType: 'json', success: function(items) { $.each(items, function(i, item) { context.log(item.title, '-', item.artist); }); } }); });
Ou quelque chose comme
this.get('#/', function(context) { context.app.swap(''); ///the 'swap' here indicates a cleaning of the view //before partials are loaded, effectively rerendering the entire screen. NOt doing the swap enables you to do infinite-scrolling / appending style, etc. // ... });
Bien sûr, d'autres frameworks MVC-client pourraient également être une option, ce qui supprime encore plus de plomberie, mais peut-être une surpêche dans cette situation.
Une comparaison assez bonne (et encore assez récente)
http://codebrief.com/2012/01/the-top-10-javascript-mvc-frameworks-reviewed/ (j'utilise Spine.js moi-même).
Enfin, j'ai pensé qu'il serait utile d'inclure une réponse que j'ai écrite il y a quelque temps qui explique en détail les meilleures pratiques (comme je l'ai vu) dans des rafraîchissements côté client, etc. Peut-être que vous l'avez trouvé utile:
Accessibilité et tous ces frameworks JavaScript
J'utilise actuellement PathJS dans l'une de mes applications. C'est la meilleure décision que j'ai prise. Pour votre utilisation particulière, regardez l' exemple HTML5 .
Le code qui fait fonctionner l'exemple (à partir de la source):
<script type="text/javascript"> // This example makes use of the jQuery library. // You can use any methods as actions in PathJS. You can define them as I do below, // assign them to variables, or use anonymous functions. The choice is yours. function notFound(){ $("#output .content").html("404 Not Found"); $("#output .content").addClass("error"); } function setPageBackground(){ $("#output .content").removeClass("error"); } // Here we define our routes. You'll notice that I only define three routes, even // though there are four links. Each route has an action assigned to it (via the // `to` method, as well as an `enter` method. The `enter` method is called before // the route is performed, which allows you to do any setup you need (changes classes, // performing AJAX calls, adding animations, etc. Path.map("/users").to(function(){ $("#output .content").html("Users"); }).enter(setPageBackground); Path.map("/about").to(function(){ $("#output .content").html("About"); }).enter(setPageBackground); Path.map("/contact").to(function(){ $("#output .content").html("Contact"); }).enter(setPageBackground); // The `Path.rescue()` method takes a function as an argument, and will be called when // a route is activated that you have not yet defined an action for. On this example // page, you'll notice there is no defined route for the "Unicorns!?" link. Since no // route is defined, it calls this method instead. Path.rescue(notFound); $(document).ready(function(){ // This line is used to start the HTML5 PathJS listener. This will modify the // `window.onpopstate` method accordingly, check that HTML5 is supported, and // fall back to hashtags if you tell it to. Calling it with no arguments will // cause it to do nothing if HTML5 is not supported Path.history.listen(); // If you would like it to gracefully fallback to Hashtags in the event that HTML5 // isn't supported, just pass `true` into the method. // Path.history.listen(true); $("a").click(function(event){ event.preventDefault(); // To make use of the HTML5 History API, you need to tell your click events to // add to the history stack by calling the `Path.history.pushState` method. This // method is analogous to the regular `window.history.pushState` method, but // wraps calls to it around the PathJS dispatched. Conveniently, you'll still have // access to any state data you assign to it as if you had manually set it via // the standard methods. Path.history.pushState({}, "", $(this).attr("href")); }); }); </script>
PathJS possède certaines des fonctionnalités les plus recherchées d'une bibliothèque de routage:
J'ai trouvé les derniers points trop attrayants. Vous pouvez les trouver ici
J'espère que vous trouvez ça utile.
J'aimerais suggérer une combinaison de
Crossroads.js en tant que routeur http://millermedeiros.github.com/crossroads.js/
Et hacher pour gérer l'historique du navigateur et les URL de hash (w / plenty of fallback solutions): https://github.com/millermedeiros/hasher/ (basé sur http://millermedeiros.github.com/js-signals/ )
Cela nécessitera encore quelques lignes de code (pour charger un contenu ajax, etc.), mais vous donner des charges et d'autres possibilités lors de la gestion d'un itinéraire.
Voici un exemple en utilisant jQuery (aucune des bibliothèques ci-dessus requiert jQuery, je suis juste paresseux …)
http://fiddle.jshell.net/Fe5Kz/2/show/light
HTML
<ul id="menu"> <li> <a href="foo">foo</a> </li> <li> <a href="bar/baz">bar/baz</a> </li> </ul> <div id="content"></div>
JS
//register routes crossroads.addRoute('foo', function() { $('#content').html('this could be ajax loaded content or whatever'); }); crossroads.addRoute('bar/{baz}', function(baz) { //maybe do something with the parameter ... //$('#content').load('ajax_url?baz='+baz, function(){ // $('#content').html('bar route called with parameter ' + baz); //}); $('#content').html('bar route called with parameter ' + baz); }); //setup hash handling function parseHash(newHash, oldHash) { crossroads.parse(newHash); } hasher.initialized.add(parseHash); hasher.changed.add(parseHash); hasher.init(); //add click listener to menu items $('#menu li a').on('click', function(e) { e.preventDefault(); $('#menu a').removeClass('active'); $(this).addClass('active'); hasher.setHash($(this).attr('href')); });
Avez-vous examiné l' échantillon SPA de BigShelf (Single Page Application) de Microsoft? Il semble que cela couvre la façon de réaliser la plupart de ce que vous demandez.
Il utilise History.js, un objet wrapper personnalisé pour contrôler facilement la navigation appelé NavHistory et Knockout.js pour la gestion des clics.
Voici un flux de travail extrêmement abrégé sur la façon dont cela fonctionne: d'abord, vous devez initialiser un objet NavHistory
qui enveloppe history.js et enregistre un rappel qui s'exécute lorsqu'il existe un changement de NavHistory
ou d'hachage:
var nav = new NavHistory({ params: { page: 1, filter: "all", ... etc ... }, onNavigate: function (navEntry) { // Respond to the incoming sort/page/filter parameters // by updating booksDataSource and re-querying the server } });
Ensuite, vous définirez un ou plusieurs modèles de vue Knockout.js avec des commandes qui peuvent être liées aux boutons de liens, etc.:
var ViewModel = function (nav) { this.search = function () { nav.navigate({ page: 2, filter: '', ... }); // JSON object matching the NavHistory params }; }
Enfin, dans votre balisage, vous utiliserez Knockout.js pour lier vos commandes à différents éléments:
<a data-bind="click: search">...</a>
Les ressources liées sont beaucoup plus détaillées en expliquant comment tout cela fonctionne. Malheureusement, ce n'est pas un cadre unique que vous cherchez, mais vous seriez surpris de voir combien il est facile de fonctionner.
Une autre chose, suite à l'exemple de BigShelf, le site que je construis est entièrement compatible avec les navigateurs, IE6 +, Firefox, Safari (mobile et de bureau) et Chrome (mobile et de bureau).
La AjaxTCR Library
semble couvrir toutes les bases et contient des méthodes robustes que je n'ai pas vues auparavant. Il est publié sous licence BSD ( Open Source Initiative ).
Par exemple, voici cinq AjaxTCR.history();
Méthodes:
Init (onStateChangeCallback, initState);
AddToHistory (id, data, title, url, options);
Avoir tout();
GetPosition ();
EnableBackGuard (message, immédiat);
L' addToHistory();
ci-dessus addToHistory();
A suffisamment de paramètres pour permettre une liaison hash profonde dans les sites Web.
Plus de bonbons pour les yeux de .com.cookie () , .storage () et .template () fournit plus que des méthodes suffisantes pour gérer les besoins en données de session .
La page Web de l'API AjaxTCR bien documentée possède une pléthore d'informations avec les doctiles téléchargeables à démarrer!
Mise à jour du statut:
Ce site Web comporte également une section de page Web Exemples comprenant des fichiers .zip téléchargeables avec des fichiers de projet prêts à l'emploi ( Client ) et Back End ( Serveur ).
Il s'agit notamment des exemples prêts à l'emploi suivants:
Cookie à sens unique
HttpOnly Cookies
Histoire de voler
Explorateur d'histoire
Il existe un bon nombre d'autres exemples qui complètent le processus pour utiliser plusieurs de leurs méthodes API, ce qui facilite l'achèvement de la petite courbe d'apprentissage.
Remarque: ExtJs History a été étendu pour optimiser les appels en double (redondants) pour add()
.
Les techniques de pjax les plus avancées commenceront même à précharger le contenu, lorsque l'utilisateur survolera le lien.
C'est une bonne bibliothèque pjax. https://github.com/MoOx/pjax
Vous marquez que les conteneurs dont ils ont besoin seront mis à jour sur les demandes suivantes:
new Pjax({ selectors: ["title", ".my-Header", ".my-Content", ".my-Sidebar"] })
Ainsi, dans ce qui précède, seul le title
, l'en .my-header
, le .my-content
.my-sidebar
seront remplacés par le contenu de l'appel ajax.
Faites attention à la façon dont votre JS se charge et détecte lorsque la page est prête. Le javascript ne sera pas rechargé sur de nouvelles pages. Faites également attention lorsque les appels d'analyse sont appelés, pour la même raison.