The following is a guest post by Jesse Shawl.
In May of 2012, Chris updated a previous post about dynamic page replacing content. This article is an update to that update, which uses the HTML5 history API for a better user experience.
Here’s a quick recap of the best practices
- Works fine with JavaScript disabled.
- It is possible to "deep link" to specific content.
- The browsers back button and forward button work as expected.
Das Problem mit URL-Hashes
Für einen einzelnen Benutzer erfüllt die vorhandene Demo die Kriterien, aber URLs sind dauerhafte Adressen und werden geteilt.
Betrachten Sie das folgende Szenario
- Ich habe einen schicken Browser mit aktiviertem Javascript. Ich surfe auf der Demoseite und finde ein tolles Produkt, das ich mit einem Freund teilen möchte.
- Ich kopiere die URL "http://example.com/#awesome-product" und schicke sie meinem Freund.
- Mein Freund hat kein Javascript aktiviert. Sie öffnet den Link in ihrem Browser und ist verwirrt, dass das tolle Produkt nicht wie erwartet geladen wird.
- Sie ist verwirrt/frustriert und schwört, example.com nie wieder zu besuchen!
DAS IST SCHLECHTES UX!
Heute werden wir die bestehende Demo verbessern, sodass die dynamische Seiteninhaltsersetzung nicht auf den Hash angewiesen ist.
Demo ansehen Dateien herunterladen
Modernizr für progressive Verbesserung
Hinweis: Die folgenden Beispiele bauen auf der vorherigen Demo auf. Laden Sie die Dateien hier herunter, um mitzumachen.
Wenn Sie Modernizr noch nicht verwenden, holen Sie es sich (ich warte). Es ist der einfachste Weg, Browserfunktionen mit JavaScript zu erkennen.
Da wir mit der HTML5-History-API herumspielen werden, müssen wir nur das Kontrollkästchen "History" aktivieren. Laden Sie den benutzerdefinierten Build hier herunter.
Fügen Sie ihn in den <head>-Bereich unserer HTML-Datei ein
<script src='js/modernizr.js'></script>
Der Test auf HTML5-History-Unterstützung ist super einfach
// dynamicpage.js
$(function() {
if (Modernizr.history) {
// history is supported; do magical things
} else {
// history is not supported; nothing fancy here
}
});
Zuerst richten wir alles ein, um die Browserhistorie zu manipulieren, und fügen dann das schicke Laden aus der vorherigen Demo hinzu.
Die Historie mit der HTML5 History API manipulieren
Die HTML5-Methode history.pushState() ermöglicht es uns,
- die URL zu ändern
- ohne Hash
- ohne Seitenaktualisierung (hier findet die dynamische Inhaltsersetzung der Seite statt)
- den Browser-Historie-Stack zu aktualisieren
- damit wir uns mit Klicks auf die Zurück- und Vorwärtstaste durch die Historie navigieren können.
Die pushState()-Methode nimmt drei Parameter entgegen
history.pushState(stateObject, "title", URL);
Wir werden in diesem Beispiel nur die URL übergeben, aber Sie können mehr über die History-API auf der Mozilla Developer Network erfahren.
Nachdem wir die URL geändert haben, werden wir eine Funktion zum Laden des Inhalts einrichten – loadContent() scheint ein guter Name zu sein.
$(function() {
if (Modernizr.history) {
// history is supported; do magical things
// hijack the nav click event
$("nav").delegate("a", "click", function() {
_href = $(this).attr("href");
// change the url without a page refresh and add a history entry.
history.pushState(null, null, _href);
// load the content
loadContent(_href); // fear not! we're going to build this function in the next code block
});
} else {
// history is not supported; nothing fancy here
}
});
Und nun müssen wir nur noch die Funktion loadContent() programmieren, was eine Übernahme von Code aus dem ursprünglichen Beispiel ist.
Code-Dump
// set up some variables
var $mainContent = $("#main-content"),
$pageWrap = $("#page-wrap"),
baseHeight = 0,
$el;
// calculate wrapper heights to prevent jumping when loading new content
$pageWrap.height($pageWrap.height());
baseHeight = $pageWrap.height() - $mainContent.height();
function loadContent(href) {
$mainContent
.find("#guts")
.fadeOut(200, function() { // fade out the content of the current page
$mainContent
.hide()
.load(href + " #guts", function() { // load the contents of whatever href is
$mainContent.fadeIn(200, function() {
$pageWrap.animate({
height: baseHeight + $mainContent.height() + "px"
});
});
$("nav a").removeClass("current");
$("nav a[href$='" + href + "']").addClass("current");
});
});
}
Browser-Klicks auf Zurück- und Vorwärts-Buttons verarbeiten
Zu diesem Zeitpunkt wird der Inhalt auf schicke Weise per Ajax geladen, aber ein Klick auf den Zurück-Button bringt uns noch nicht zurück...
Die History-API gibt uns Zugriff auf das popstate-Ereignis, das jedes Mal ausgelöst wird, wenn sich der Historie-Stack ändert (lies: Zurück- und/oder Vorwärts-Buttons werden geklickt). Immer wenn dieses Ereignis ausgelöst wird, müssen wir nur unsere loadContent()-Funktion aufrufen.
$(window).bind("popstate", function() {
link = location.pathname.replace(/^.*[\\/]/, ""); // get filename only
loadContent(link);
});
Eine kleine Hausaufgabe
Zum Zeitpunkt des Schreibens tritt das popstate-Ereignis in Chrome beim Laden der Seite auf. Das bedeutet, es werden zwei Anfragen gestellt:
- Die ursprüngliche HTTP-Anfrage für wasauchimmer.html
- Die Anfrage von
$.loadin unsererloadContent()-Funktion
Es gibt ein paar verschiedene Möglichkeiten, damit umzugehen, aber ich überlasse Ihnen die Entscheidung, was am besten funktioniert.
Wenn Sie immer noch Benutzer unterstützen, die Javascript deaktiviert haben, sind Sie Teil des Problems, nicht der Lösung.
Webentwickler müssen aufhören, ihre Zeit damit zu verschwenden, sich um einen winzigen Teil der Internetnutzer zu kümmern, und stattdessen dazu beitragen, das Web voranzubringen, indem sie das Web zu einem schlechten Ort machen, wenn Sie „altes IE“ verwenden oder Javascript deaktiviert haben.
Das Web im Jahr 2013 zu nutzen bedeutet, Javascript zu nutzen.
Ich stimme zu 100% zu.
Besonders mit „aufhören, ihre Zeit damit zu verschwenden, sich um einen winzigen Teil der Internetnutzer zu kümmern“.
Zustimmen
Ebenso.
Ich stimme in gewisser Weise zu ... Ich ignoriere alte IE-Versionen bei der Entwicklung der meisten Websites für mich selbst. Mein Unternehmen arbeitet jedoch mit vielen staatlichen Straßenverkehrsbehörden und anderen Regierungsstellen zusammen, die IE7, IE8 und andere schlimme Dinge verlangen. Obwohl ich also nicht dazu beitragen möchte, hängt mein Job und mein Gehalt manchmal davon ab. :-/ Beschuldigen Sie die langsamen Regierungsbehörden, wenn Sie jemanden beschuldigen wollen.
Obwohl ich zustimme, dass jeder, der mit deaktiviertem Javascript surft, wahrscheinlich zu einer sehr sehr kleinen Gruppe gehört und sich wahrscheinlich nicht bewusst ist, dass es deaktiviert ist, und dass der Weg nach vorn darin besteht, im Allgemeinen auf rückwärtskompatible Praktiken zu verzichten, denke ich auch, dass es sicherlich Situationen gibt, in denen Kunden Forderungen haben, die Teil eines größeren Bildes sind, als sie realisieren, und Kompatibilität für alle ihre Kunden erwarten, auch für die winzige Anzahl, die vielleicht kein Java aktiviert hat, und für diese Situationen bin ich wirklich froh, eine so hervorragende Ressource wie diese Website zu haben, die bei diesen spezifischen Szenarien hilft.
Danke Chris und Jesse!
Zur Klarstellung, diese Demo tut genau das: nichts Besonderes für Nicht-JS-Benutzer. Dennoch funktioniert sie.
Ich hasse es auch, dogmatisch über etwas zu sein, wie z. B. ob man Nicht-JS-Benutzer unterstützt oder nicht. Ich habe an vielen Apps gearbeitet, die den Nicht-JS-Fall weitgehend ignoriert haben, und es war nie ein großes Problem.
Gibt es Statistiken über den Prozentsatz der Benutzer, die kein JS verwenden? Ich müsste schätzen, dass es unglaublich klein ist.
Der Prozentsatz der Benutzer, die JS explizit deaktiviert haben, ist gering. Der Prozentsatz der Benutzer mit verrückten GreaseMonkey-Skripten und Chrome-Erweiterungen, die Ihren DOM manipulieren und Ihr JS zerstören, ist riesig, insbesondere wenn Ihre Zielgruppe Entwickler sind. Progressive Enhancement FTW.
Ich stimme Ben zu. Es geht nicht darum, Benutzer mit deaktiviertem JS zu unterstützen, sondern darum, Webkonventionen nicht zu brechen.
Was passiert, wenn das Drittanbieter-Skript einen JS-Fehler in der Produktion auslöst und Sie die Lösung nicht progressiv verbessert haben? = kaputte URLs.
Man muss sich keine Sorgen um Benutzer machen, wenn JavaScript deaktiviert ist. Es geht um Suchmaschinen.
Wenn Inhalte nur durch eine JavaScript-Funktion aktiviert würden, könnten sie nicht gecrawlt und indiziert werden.
Ich muss Jon weitgehend zustimmen. Leute werden nicht das Gefühl haben, sich zur Aktualisierung verpflichtet zu fühlen, wenn sie ständig von der Entwickler-Community bedient werden. Dennoch glaube ich, dass mehr Überzeugung besser ist, als ihnen einfach zu erlauben, eine schrecklich aussehende, nicht funktionierende Website zu laden.
Ich wäre viel eher dafür, dass die Entwickler-Community universell eine Methode verwendet, die die Benutzer darüber informiert, dass sie kein Javascript verwenden und entweder ihren Browser aktualisieren oder die Website in ihren Skriptblockern zulassen sollten. Höflich und hilfreich zu sein hilft Menschen sehr bei der Annahme neuer Technologien – besonders wenn es sich um Leute handelt, die sich seit frühem IE nicht zum Upgrade entscheiden konnten.
Vielleicht sollten wir Nicht-JS-Benutzer ignorieren, vielleicht auch nicht. Das spielt keine Rolle. Sie haben einfach nicht Recht, wenn Sie sagen: „Webentwickler müssen aufhören, ihre Zeit zu verschwenden“, denn das tun sie nicht! Wissen Sie überhaupt, wie schwer es ist, alle Benutzer zufrieden zu stellen? Und wissen Sie überhaupt, dass ein Entwickler, der dazu in der Lage ist, sicherlich das Recht hat, als Experte, Meister, qualifiziert oder wie auch immer Sie ihn nennen möchten, bezeichnet zu werden. Webentwicklung (die Design, Programmierung, die Kombination beider, Personalisierung Ihrer Apps, Verbesserung ihrer Zugänglichkeit, Benutzerfreundlichkeit, Übersichtlichkeit und Einfachheit, Verwaltung von Inhalten, Erstellung von CMS) besteht nicht darin, Websites sehr, sehr schnell zu machen, nur um Geld zu verdienen. Zumindest meiner Meinung nach. Wenn ein Entwickler das tut, was er/sie tut, wirklich genießt, seine Arbeit liebt und sie mehr als nur ein Hobby geworden ist, dann ist er auch jederzeit bereit und willens, neue Dinge zu lernen, seine Fähigkeiten zu trainieren, ein besserer Designer zu werden. Es geht nicht um… die Nutzung von Javascript im Jahr 2013 oder etwas Ähnliches. Es geht um den WUNSCH, besser zu codieren, besser zu designen, besser zu entwickeln. Für sich selbst.
Ich denke, viele von Ihnen verpassen den Punkt hier und verstehen die Umstände nicht.
Wenn Sie eine Portfolio-Website erstellen, um Ihre Fotografie zu präsentieren, müssen Sie sich wahrscheinlich nicht wirklich um diejenigen kümmern, die kein JavaScript aktiviert haben. Wenn Sie ein Webportal im Unternehmensmaßstab für Millionen bis Hunderte von Millionen von Menschen erstellen, dann denke ich **absolut**, dass Sie sich darum kümmern müssen. Obwohl 90 % von Ihnen sich nicht um Nicht-JavaScript-Benutzer kümmern, gibt es immer noch eine große Anzahl von uns, die sie unterstützen müssen.
@Jonathan Graft hat einen guten Punkt angesprochen, dass viele von uns, die in der Web-Welt arbeiten, immer noch für staatliche Straßenverkehrsbehörden und Regierungswebsites entwickeln und codieren müssen, die gesetzliche Web-Anforderungen haben.
Viele erkennen auch nicht, dass Websites, die insbesondere in Unternehmensumgebungen erstellt werden, starke Browser-Kompatibilität und progressive Verbesserung **benötigen**. **Kunden in irgendeiner Form zu verweigern, bedeutet potenziell zukünftiges Geschäft zu verweigern.** Nur weil Sie die neueste Version von Chrome oder Firefox verwenden, heißt das nicht, dass Joe Schmoe, der an einem Bankcomputer auf der Arbeit arbeitet, immer noch bei IE7 feststeckt und Ihre Website nutzen muss. Joe Schmoes IT-Richtlinie könnte auch standardmäßig deaktiviertes Javascript in seinen Browsern haben. Erfolgreiches Geschäft beruht darauf, auf die Bedürfnisse Ihrer Kunden einzugehen, nicht auf Ihre Bedürfnisse.
Denken Sie mindestens ein Jahrzehnt zurück und weiter, als überall Flash-Websites waren. Kein Unternehmen machte eine „Flash“-Website und nur eine Flash-Website. Es gab fast immer eine normale Webversion. Der Grund? Viele Leute hatten kein Flash und wollten keine potenziellen Kunden ausschließen.
Auch wenn es für manche einfach ist, zu sagen, dass wir etwas nicht mehr tun oder unterstützen sollten, stellen Sie sicher, dass Sie sich bewusst sind, was es beeinflussen könnte, bevor Sie solche Entscheidungen treffen.
Obwohl ich zustimme, dass die Unterstützung dieser Benutzer mühsam sein kann, müssen wir uns immer noch um diejenigen kümmern, die nicht auf dem neuesten Stand sind, bis das Web in eine standardkonformere Richtung gegangen ist.
Ich denke, als Webentwickler sollte man verstehen, wie das Web funktionieren sollte. Mark Massé erklärt im REST API Design Rulebook, dass
Mit anderen Worten, ich halte es für unklug, Benutzer, die kein JavaScript aktiviert haben oder einen alten Browser verwenden, zu ignorieren und stattdessen mit abnehmender Degradation zu entwickeln.
Ich stimme zu. Wenn Sie heutzutage kein JS verwenden, dann gut, verlassen Sie das Internet.
Viele Tracking-Technologien erfordern JS, um zu funktionieren.
NoScript ist eine der beliebtesten Firefox-Erweiterungen. Sogar die deutsche Regierung empfiehlt ihren Bürgern die Nutzung.
Benutzer, die JS absichtlich deaktivieren, sind wahrscheinlich datenschutzsensibler als andere, und daher blockieren sie möglicherweise auch andere statistische Methoden (wie Web Bugs).
Daher ist es schwieriger, Besucher ohne JS zu verfolgen und zu zählen. Viele Tracking-Methoden ignorieren sie. Solche Statistiken sind daher naturgemäß fehlerhaft, wenn Sie wissen möchten, wie viele Ihrer Besucher JS deaktiviert haben.
Welche Browser unterstützt diese Methode?
Die meisten modernen! http://caniuse.com/#feat=history. Da wir progressive Verbesserung praktizieren, funktioniert die Seite einwandfrei in Browsern, die die History-API nicht unterstützen.
Kleine Anmerkung:
delegate()wurde ab jQuery 1.7 durchon()ersetzt – vielleicht sollten Sie das aktualisieren!Gute Nachlese Jesse. Lassen Sie mich etwas hinzufügen. Beim Teilen eines Links auf Facebook wird der Seitentitel und die Meta-Beschreibung abgerufen. Indem Sie Ihre Website ohne JavaScript funktionstüchtig machen, ist dies ein guter Anfang für eine erfolgreiche Social- und Suchmaschinenoptimierung.
Darüber hinaus war ich an einem Projekt beteiligt, bei dem wir vor etwa einem Jahr ein ähnliches Setup implementiert haben. Die Absprungrate fiel dramatisch von 43% auf 7%. Die durchschnittliche Anzahl der Seiten pro Besuch stieg von 3% auf 14%. Die durchschnittliche Verweildauer auf der Website verdreifachte sich und die Seitenaufrufe ver siebenfachten sich in der ersten Woche nach der Einführung. Inhalte, die nicht auf Facebook geteilt werden konnten, waren jetzt möglich. Google und Bing konnten jeden Artikel erreichen. Weniger störende Seitenaktualisierungen mit schnelleren Ladezeiten. Bessere Analysen. Was für eine Erfahrung!
Wenn wir doch nur Ihren Code in all die Fotogalerien, Diashows, Parallax-Scrollings, Modals usw. integrieren könnten, die wir heute in Websites einbauen. Stellen Sie sich vor, wie einfach das Teilen dann wäre!
(Ohne den Zurück-Button zu beeinträchtigen und uns die Nutzung nach unseren eigenen Bedingungen zu ermöglichen.)
Hmmm… das wäre praktisch für Infinite Scrolling…wenn das überhaupt möglich ist.
http://www.usabilitypost.com/2013/01/07/when-infinite-scroll-doesnt-work/
Stellen Sie sich vor, die URL ändert sich beim Scrollen, damit Sie dort bookmarken können, wo Sie zuletzt aufgehört haben. Dann ist die Paginierung möglicherweise nicht mehr nötig.
Sie haben einen ausgezeichneten Punkt angesprochen, dass der Kern Ihrer Website ohne Javascript funktionieren muss, wegen aller Suchmaschinen und sozialen Websites. Der Traffic ist zu wertvoll, um Ihre Website nicht für diese javascript-ignorierenden Bots freundlich zu machen.
Es ist ohnehin nicht schwer zu tun. Nicht um hart zu klingen, aber es ist wahrscheinlich Faulheit auf Seiten des Entwicklers. Sie sollten ein grundlegendes Website-Frontend erstellen, das ohne JS funktioniert, und es dann mit den neuesten Trends erweitern, wie Sie erwähnen.
Vielleicht dampfe ich nur ab, weil ich zu viele Websites mit dem Infinity Scrolling erlebt habe, wo ich versehentlich auf etwas klicke und wenn ich zurückgehe, fängt es wieder von vorne an. NEIN!!!! *Schüttelt die Faust in den Himmel*
Ich stimme @Jon Hobbs zu, sich um diese Benutzer zu kümmern ist so ziemlich nutzlos
Kann das Problem von Landing-URL-Hashes jedoch nicht serverseitig verwaltet werden?
Vielleicht könnte man das, aber Hashes wurden hauptsächlich verwendet, damit man nicht mehr als einmal mit dem Server interagieren musste – das spart HTTP-Anfragen und die lästige Seitenaktualisierung. Wenn diese Demo nicht mit dem CDN von Google für die jQuery-Datei verbunden wäre, könnten Sie die Tabs ohne Internetverbindung navigieren. Speichern Sie die Seite lokal, trennen Sie Ihre Verbindung und probieren Sie es aus. Dies wäre nicht möglich, wenn der Server involviert sein müsste.
Ich hoffe, das war hilfreich.
Ich scheitere an der Hausaufgabe. :) Wie verhindert man, dass das popstate-Ereignis beim Laden der Seite ausgelöst wird?
Hier ist der Trick, den ich benutze
Argh, ich möchte meinen Kommentar bearbeiten, kann es aber nicht. Die jQuery-Funktion, die verwendet werden sollte, ist
live(anstelle vondelegateundon).@Guilherme „on“ ist immer noch korrekt. Laut jQuery API: „Ab jQuery 1.7 bietet die .on()-Methode alle Funktionalitäten, die zum Anhängen von Ereignishandlern benötigt werden“. Wenn Sie on wie live behandeln wollten, könnten Sie es von body delegieren, was immer noch effizienter ist als die frühere live-Methode (sie verwendet document). Offensichtlich ist die Effizienz umso höher, je weiter unten im Baum Sie delegieren können.
$("body").on("click", "a", function(){});Ich scheitere auch an der Hausaufgabe. Hauptsächlich, weil ich neu in Javascript bin. Wie wird diese Korrektur implementiert?
Zwei Anmerkungen: Die erste ist einfach, dass ich nicht so etwas Großes wie Modernizr laden würde, wenn man einfach prüfen könnte, ob
window.history.pushStatedefiniert ist – dieses Skript-Tag wird das Rendern blockieren und einige zusätzliche Server-Round-Trips hinzufügen, um ein Dutzend Bytes JavaScript zu ersetzen.Zweitens, als Antwort auf die Leute, die dafür plädieren, JavaScript-lose Benutzer zu ignorieren: Erinnern Sie sich, was passiert ist, als Gawker, Twitter usw. das taten? Jeder Fehler in Ihrem JavaScript, die Netzwerkverbindung des Benutzers usw. bricht Ihre Website und lässt Sie schlecht aussehen – was der Schlüssel dazu ist, warum alle von dieser Strategie abgerückt sind. Anders ausgedrückt: Wenn Sie progressive Verbesserung nutzen, sieht Ihre Website immer noch gut aus, erfordert aber keine zusätzliche Entwicklungsarbeit, um schnell zu laden, robust zu sein, gut mit Suchmaschinen und anderen Robots zu funktionieren usw.
Der Vorteil der Verwendung von Modernizr ist, dass sie immer die Extrameile gehen und Eigenheiten bei der Feature-Erkennung behandeln, an die Sie vielleicht nicht gedacht hätten.
In diesem Beispiel hat History eine Eigenheit
https://github.com/Modernizr/Modernizr/blob/master/feature-detects/history.js
@Chris Coyier: guter Punkt. In diesem Fall sind die eigentlichen Feature-Erkennungen unter 200 Bytes, was ungefähr an dem Punkt ist, an dem ich sie einbetten würde, um den zusätzlichen RTT zu vermeiden. Allein die HTTP-Anfrage-Header würden mehr Traffic verursachen…
@Rob: Der Hauptpunkt war, dass ein Skript-Tag das weitere Laden und Rendern der Seite blockiert, bis das Skript vollständig ausgeführt ist. Wenn Sie ältere Android-Versionen unterstützen müssen, würde ich dieses Skript einbetten, um die Bestrafung aller anderen zu vermeiden.
Sie müssen nicht die vollständige Modernizr-Datei laden, auf der Website können Sie jede benötigte Option auswählen und ein kleines JS herunterladen.
Benutzerdefinierter Build von Modernizr FTW! Ich beginne normalerweise mit einem vollständigen Build und prüfe dann vor der Veröffentlichung, was ich tatsächlich verwende, und erstelle einen benutzerdefinierten Build nur mit diesem. Das Einbetten des Skripts blockiert übrigens immer noch.
Ein weiterer Grund, Modernizr zu verwenden: Es enthält den html5shiv (es sei denn, Sie bitten es ausdrücklich nicht), sodass Sie ältere Browser als HTML5 unterstützen können, die usw. nicht verstehen.
Ich stimme der Ansicht zu, dass Benutzer, die JS deaktiviert haben, im Allgemeinen eine schreckliche Web-Erfahrung haben werden. Nichtsdestotrotz halte ich es für eine gute Praxis und vernünftig zu erwarten, dass das einfache Anzeigen und Laden von Inhalten nicht von Javascript abhängt.
Jedenfalls hatte ich keine Ahnung, dass es möglich ist, die URL zu ändern, ohne Hashes zu verwenden und ohne die Seite zu aktualisieren. Sehr cooler Tipp.
Entschuldigung, vielleicht übersehe ich etwas... aber wenn das JS eines Benutzers deaktiviert ist, wie macht eine JS-basierte Lösung die Dinge besser?
Soweit ich weiß, liegt das Problem hier in der URL, die vom JS-Benutzer an den Nicht-JS-Benutzer gesendet wird. Diese Korrektur erstellt eine URL, die für beide freundlich ist. Wie Aaron bereits erwähnte, macht es den Inhalt einfacher zu teilen.
Es tut nichts Besonderes für Nicht-JS-Benutzer, die die Website selbst durchsuchen, aber das ist irrelevant, da dies ein anderes Szenario ist als das oben beschriebene.
Ich sehe auch nicht, warum Push State und Pop State so viel besser sind als die #Tag-Endung der URL.
Vergessen Sie nicht, dass Sie beim dynamischen Laden von Inhalten auf die Seite einen Teil der HTML-Seite laden. Wenn Sie eine nicht-javascript-freundliche URL erstellen, müssen Sie auf dem Server eine zweite Seite implementieren, die Ihnen auch die vollständige Seite anzeigt!
Das bedeutet, dass viel Arbeit erforderlich ist, um sowohl Clients mit als auch ohne Javascript zu unterstützen!
Für mich ist die Mühe nicht wert.
Ich unterstütze diejenigen, die sagten, sie sollen die Nicht-JS-Benutzer vergessen. Es ist unwahrscheinlich, dass diese Benutzer versuchen werden, Ihre schicke moderne Website ohne aktiviertes Javascript zu besuchen, und es ist unwahrscheinlich, dass sie sich für Links zu solchen Websites von ihren Freunden interessieren. Für die moderne Webentwicklung glaube ich eher, dass JS eine Standardfähigkeit ist, und die Realität ist so nah an diesem Ideal, dass es genauso gut als wahr betrachtet werden könnte. Kein Bedarf, Zeit mit Funktionen mit so wenig Nutzen zu verschwenden.
Ich habe Ihren Artikel sorgfältig gelesen, leider etwas zu technisch für mich. Ich werde versuchen, mich besser zu informieren.
Wirklich interessante Abhandlung... danke für den Beitrag!
Wie wäre es mit einem doppelten Fallback? Reihenfolge: pushstate, hashbang, normal.
Sie werden das Risiko, dass jemand eine nicht funktionierende URL auf Nicht-JS-Puristen erhält, erheblich verringern, anstatt das Risiko ganz zu beseitigen. Aber Sie bieten etwa 10-20 % Ihrer Zielgruppe die gleiche Erfahrung wie den Benutzern moderner Browser. Das kann für UX sehr wichtig sein, wenn der Designer, wie in meinem Fall, langsame Hintergrundbildwechsel wünschte.
Außerdem wird oft vergessen, (Dinge wie) document.title zu aktualisieren (verwenden Sie dafür immer natives JS). Andernfalls erhalten auch Lesezeichen einen kaputten Titel.
Der Code
wird ein böses globales Objekt erzeugen.
Falls sich jemand fragt: Wenn du das `var`-Schlüsselwort in JS auslässt, wird es zu einem impliziten globalen Wert.
Ich benutze diese Bibliothek für plattformübergreifende Kompatibilität
https://github.com/balupton/history.js
Sie hat auch eine optionale Fallback-Lösung mit #Hashtags, um die Variablen auf Browsern ohne History-Unterstützung zurückzubekommen. Die Hashes sind nicht wirklich elegant, aber sie funktionieren.
Ich kenne keine andere Bibliothek, diese wurde schon länger nicht mehr aktualisiert, aber sie funktioniert immer noch.
Ich benutze diese auf http://www.area.fr/ (allerdings ohne Hashtag-Fallback-Unterstützung).
Für all jene Hasser von „Besucher mit deaktiviertem JavaScript“... Wenn ich eine Website erstelle, denke ich selten oder nie über diese Besucher nach. Aber irgendwie wird das Endprodukt, das ich dem Kunden liefere, progressiv verbessert. Warum? Weil dem Kunden das Teilen und eine ordentliche Indexierung in Suchmaschinen wichtig ist. Wenn deinem Kunden die Suche und soziale Medien wichtig sind, musst du progressive Enhancement in Betracht ziehen. Verlang mehr Geld, bilde deinen Kunden auf – was auch immer nötig ist. Nicht alle unsere Kunden sind wie Nike (nikeworld.com) und können damit durchkommen. Sie waren die Ersten mit Parallax Scrolling. Sie haben Kobe!
Jetzt arbeite ich auch an verschiedenen Projekten, die Angular.js und Handlebars.js verwenden. Ich habe den Offline-First-Ansatz gewählt. http://developer.chrome.com/apps/offline_apps.html Das bedeutet, dass diese App überhaupt nicht funktioniert, wenn JavaScript deaktiviert ist. Aber das ist in Ordnung, weil wir nicht wollen, dass soziale Medien und die Suche eine Rolle spielen für eine App, die nur von Menschen genutzt werden soll.
Ich hoffe, das war informativ. (
Das ist einfach genial. Keine störenden Hashtags in der Website-URL, und das UX ist auch cool. Beide Beispiele sind gut.
Ich arbeite nicht viel mit Nicht-JS-Benutzern, sondern hauptsächlich für Cross-Browser-Kompatibilität; und es funktioniert gut mit IE7, IE8 und höher.
Dieser Artikel kommt extrem gelegen. Ich hatte gerade eine Diskussion mit einem Kunden über Single-Page- vs. Multi-Page-Websites und JavaScript vs. Nicht-JavaScript-Browserunterstützung. Jede Website, die ich baue, funktioniert mit deaktiviertem JavaScript. Das gefällt mir so. Ich kann nicht vorschreiben, wie Benutzer das Web durchsuchen, und Google Analytics kann mir nicht sagen, ob Benutzer JavaScript aktiviert oder deaktiviert haben, da GA nur Benutzer mit aktiviertem JavaScript verfolgen kann. Modernizr hat diesen Ansatz einfach gemacht, sodass ich mein CSS mit Blick auf die Funktionalität schreiben kann.
Ich werde dieses Tutorial ausprobieren müssen. Es sieht sehr sauber aus.
Das scheint mit IE 9 nicht zu funktionieren. Anstatt den Inhalt dynamisch zu laden, geht es direkt zum Link im href.
Mein Freund hat kein Javascript aktiviert. Sie öffnet den Link in ihrem Browser und ist verwirrt, dass das tolle Produkt nicht wie erwartet geladen wird.
Wer sind diese Leute? Und warum bist du mit ihnen befreundet?
Super! Ich hatte eine Situation, in der ein Kunde glaubte, die URL mit dem Hash-Zeichen sei ein Zeichen für einen Fehler und sie sähe hässlich aus. Ich habe vergeblich versucht, ihn zu überzeugen. Das war das letzte Mal, dass ich Ajax für jemanden implementiert habe. Das scheint die Antwort darauf zu sein, danke Chris.
Nun, leider werden einige Methoden wie „history.pushState()“ von alten Browsern nicht unterstützt...
@ Chris (#comment-251890). Meinst du also, wenn man etwas wie
if (history.pushState) {...
}
anstatt Modernizr verwendet, werden keine „Eigenheiten“ berücksichtigt?
Warum nicht einfach die gesamte Website erstellen und die hrefs mit Hashes beim Laden durch JavaScript ersetzen? Auf diese Weise hast du immer noch schöne Hashtags, oder übersehe ich etwas?
Wie wirkt sich das auf die Analytik aus? Zählt `history.pushState` als separate Seitenaufrufe?
Im Net-Panel von Firebug bemerke ich, dass das Klicken auf Links keinen neuen Seitenaufruf anzeigt...
Moment, wie kann man die HTML5 History API nutzen, wenn man dafür JavaScript braucht? Ist der Zweck damit nicht erfüllt?
Wenn du auf http://www.danperceval.com gehst, siehst du, dass der Bilder-Slider (der Autos) im Hauptinhaltsbereich funktioniert. Aber wenn du auf ABOUT klickst, funktioniert er nicht, aber das CSS scheint zu funktionieren. Und in Chrome und Safari funktioniert der Bilder-Slider generell nicht, selbst beim Laden der Seite. Das Laden von Inhalten mit Dynamic Page Script scheint keine jQuery oder andere Skripte zu laden oder zum Laufen zu bringen. Außerdem bin ich Anfänger in CSS und verstehe überhaupt nichts von Skripting. Könntest du dir bitte meine Seite (www.danperceval.com) ansehen und herausfinden, warum jQuery nicht funktioniert? Danke.
Ich benutze dieses Skript, aber es stört viele andere zufällige Dinge auf meiner Website. Zum Beispiel funktionieren Shadowbox und die Google Maps API nicht mit
$(window).bind(‘popstate’, function(){
_link = location.pathname.replace(/^.*[\\/]/, ”); //Nur Dateiname abrufen
loadContent(_link);
});
Außerdem habe ich Probleme mit Links innerhalb bestimmter Abschnitte, da der Dateiname nicht in das Stammverzeichnis zurückgeführt wird.
Ich bin generell ein Fan von progressivem Enhancement, aber das Problem mit der History API ist, dass du möglicherweise nicht richtig die Anzahl der IE8/IE9-Benutzer gegen die Anzahl der Besucher mit deaktiviertem JS abwägst. Wenn deine Website eine beträchtliche Anzahl von IE8/IE9-Benutzern hat, hast du deren Erlebnis stark verschlechtert, als du sie jedes Mal zum Nachladen zwingst, wenn sie auf etwas klicken. (Ein erheblicher Prozentsatz mobiler Benutzer hat ebenfalls noch Browser ohne History API, wenn Mobilgeräte dein Ding sind.) Die meisten/alle dieser Benutzer hätten mit eingeschalteten Hashes ein besseres Erlebnis haben können.
Best Practices sind großartig, aber für mich ist die ultimative Best Practice, die beste Erfahrung für die größte Anzahl von Besuchern meiner Seiten zu bieten. Wenn ich eine großartige Erfahrung für 99 % meiner Besucher bieten kann und 1 % (die Ludditen ohne JS) einen Fehlerbildschirm erhalten, nehme ich das gerne an. Das ist weitaus besser, als 80 % meiner Besucher ein funktionierendes, aber mieses Erlebnis zu bieten.
(Ich habe auch schon gesehen, wie Entwickler sich mit solchen Ansätzen in Schwierigkeiten gebracht haben (z. B. Jquery Mobile). HTML-Chirurgie zur Unterstützung des dynamischen Ladens von vollwertigen Seiten ist normalerweise komplizierter und fehleranfälliger als das Laden und Rendern von Snippets oder das einfache Ein- und Ausblenden von Inhalten von einer einzigen Seite.)
Wenn eine bestimmte Seite zusätzliches JavaScript und/oder ein zusätzliches Stylesheet hat, gibt es eine Möglichkeit, diese ebenfalls zu laden?
var $myNav = $(“.myNav a”),
$mainContent = $(“.main-content”);
Vielleicht bilde ich es mir nur ein, aber ich denke, das sieht besser aus und es spielt besser mit Bootstrap zusammen.
Habe den Code etwas gestrafft.
Wenn du keinen vollständigen Seiten-Fade-In möchtest, kannst du diese Zeile einfach entfernen.
Viel Spaß.
Ich bin immer noch ein bisschen neu in JS, Chris Coyier oder irgendjemand anders, könntest du bitte die Antwort(en) auf die Hausaufgaben posten? Nichts von dem, was gepostet wurde, funktioniert richtig.
Vielen Dank im Voraus.
Ich stelle fest, dass dies kaputtgeht, wenn die Links, die den dynamischen Inhaltsaustausch auslösen, sich innerhalb des `<div id="guts">` befinden.
Das schien in der vorherigen Version kein Problem zu sein. Keine Ahnung, wie ich das beheben kann. Jeder Rat wäre willkommen.
Deshalb habe ich die Verwendung komplett eingestellt.
Je nach deiner Website, wenn du dynamische Includes verwendest (z. B. ?page=Example) und die einzige Lösung, an die ich denken kann, ist das erneute Laden des Skripts innerhalb des Skripts, was zu einem üblen Speicherleck führt.
Aber wenn deine Links direkt zur Datei führen (z. B. \example.html), kannst du diese Zeile wie folgt ändern:
zu
Da du die HTML-Datei direkt lädst, musst du nicht, dass der Code nach `.guts` auf der gesamten Seite sucht, im Gegensatz zu PHP-Includes, die die gesamte Seite zusammenstellen, bevor das JS darauf zugreifen kann.
Deine Lösung ist **einfach**, **sauber** und **klar**. Vielen Dank!!!
Wenn ich lokal in Chrome Vorschau sehe, funktioniert es nicht :/
Safari ist in Ordnung, aber in Chrome wird „guts“ leer und bleibt leer.
Mache ich etwas falsch?
Link: http://stackoverflow.com/questions/23629244/popstate-html5-and-ajax-load-content
Wir haben ein Problem mit dem `popstate`-Ereignis. Wir haben eine Mini-Website mit dieser neuen erstaunlichen Eigenschaft erstellt und ich hatte keine Probleme, bis ich eine Kontaktseite mit Ajax-Antworten erstellt habe.
mein script.js (ich habe unnötige Skripte und Steuerelemente entfernt) und HTML-Code. Wenn ich versuche, direkt zur Kontaktseite zu gehen, habe ich keine Probleme mit dem Ajax-Aufruf. Gib alle Informationen ein, klicke auf den Absenden-Button und Ajax ruft das PHP-Skript (im Hintergrund) auf, das die E-Mail sendet, ohne die Seite zu ändern.
Das Problem beginnt, wenn ich zu einer anderen Seite wechsle und dann auf den Link zur Kontaktseite klicke. Jetzt, wenn ich versuche, auf den Absenden-Button zu klicken, wird der Ajax-Aufruf nicht ausgelöst und der Browser (Chrome und Firefox) ruft direkt das PHP-Skript in der Formularaktion auf und ändert die Seite (nicht im Hintergrund). Haben wir eine Lösung??? Vielen Dank!
$(function () {
}); // Ende des Submit-Event-Handlers
});// Ende der Funktion
Ich habe dies gerade zu einer Website hinzugefügt, die ich derzeit baue, und alles funktioniert gut, bis auf eine Sache.
Beim ersten Laden der Indexseite funktioniert der Slider, den ich benutze, aber wenn ich erneut auf den Link zur Indexseite klicke, wird das Slider-Skript nicht geladen, sodass ich nur die Listenelemente sehe und nicht den Slider.
Irgendwelche Ideen dazu?
Hier ist der Link zur Seite: http://www.level26.at/testsites/dj-yeezy/
Ich habe dieses Skript erfolgreich in mehreren Projekten verwendet.
Jetzt möchte ich es mit Joomla! 3 verwenden.
Gibt es eine Möglichkeit, es für Joomla anzupassen?
Meine Website verwendet unterschiedliche JavaScripts für jede Seite aufgrund des benötigten Inhalts. Wie lade ich das Skript für den Inhalt mit dem Inhalt?
…
Ich habe versucht, alle Skripte von der Indexseite zu referenzieren, ich habe versucht, die Skripte innerhalb des geladenen Inhalts zu referenzieren, ich habe sogar versucht, Skripte durch Erstellen einer Skriptvariable mit einer ID und dem Austauschen aus dem Inhalts-Div zu ersetzen.
Jede Hilfe wäre sehr willkommen.