Antworten auf deine Fragen:
Neues Thema erstellen

Popstate bei Ajax

sapta

Gesperrt

Hallo,

ich habe eine Frage.
Bei einem Ajax-Load wird die URL mit history.pushstate() verändert. Nach dem Ajax Load funktionieren die Browser-Buttons nicht mehr. Deshalb muss man ja das popstate-Event auslösen und den Inhalt dann mit Ajax wieder laden.
Meine Frage ist: Woher weiß meine popstate-Funktion welche Seite sie laden soll?
Code:
        window.onpopstate = function(event) {
            
            var uri = document.URL;
            alert(uri);
            
        };
Diese Variable uri verändert sich nach dem zweiten Klick auf den Browser-Zurück-Button nicht mehr (sofern so oft Inhalte geladen wurden) und somit weiß meine Funktion auch nicht mehr welchen Inhalt sie laden soll.

Gibt es eine andere Möglichkeit, ggf. über das stateObject?
 

mindraper

me[code].Java(Script)

AW: Popstate bei Ajax

moin,

history.pushState verändert nicht einfach nur die URL, sondern fügt einen einen eintrag (state object, titel, url) in das history object ein, und zwar jedesmal, wenn die methode genutzt wird. beispiel:

Code:
var stateOne,
    stateTwo,
    stateThree;

// define state-object which will be added to the history
stateOne = {
    title: 'one',
    url: 'some.url/to-save/one',
    step: 'first'
};

stateTwo = {
    title: 'two',
    url: 'some.url/to-save/two',
    step: 'second'
};

stateThree = {
    title: 'three',
    url: 'some.url/to-save/three',
    step: 'third'
};

stateOne, -Two und -Three sind die zu speichernden state-objects. jetzt werden alle drei nacheinander zur history hinzugefügt:

Code:
// add stateOne to history
history.pushState(stateOne, stateOne.title, stateOne.url);

// add stateTwo to history
history.pushState(stateTwo, stateTwo.title, stateTwo.url);

// add stateThree
history.pushState(stateThree, stateThree.title, stateThree.url);

soweit klar? ok. normalerweise würde man natürlich andere informationen in einem state-object haben als einen titel und eine url, aber das ist für die erklärung der funktionalität ja absolut irrelevant.

in dem popstate eventlistener hast du als argument – wie du schon korrekt in deinem beispiel code geschrieben hast – ein sog. event-object. dieses hat eine eigenschaft namens "state", welches dir das entsprechende state-object liefert (stateOne, -Two und -Three).

in meinem beispiel ist das aktuelle state-object bzw. der aktuelle eintrag in der history also "stateThree". benutzt du jetzt den zurück button des browsers, liefert dir event.state das state-object "stateTwo":

Code:
// also possible: window.onpopstate = function (event) { /* code */ }
window.addEventListener('popstate', function (event) {
    // logs the corresponding state-object to the console
    console && console.log(event.state);

    alert(event.state.step);
    alert(event.state.url);
    alert(event.state.title);
});

beim ersten benutzen des zurück buttons bekommst du drei alerts, mit folgenden meldungen:
'second'
'some.url/to-save/two'
'two'

in deiner konsole wird ein object geloggt, das dem state-object "stateTwo" entspricht.

benutzt du den zurück button nochmals, bekommst du wieder drei alerts:
'first'
'some.url/to-save/one'
'one'

und in deiner konsole wird ein object geloggt, das "stateOne" gleicht.
 

sapta

Gesperrt

AW: Popstate bei Ajax

Danke für die Antwort.
Das leuchtet alles ein.
Habe drei Fragen dazu:

1.) Welche Informationen könnten denn noch im stateObject gespeichert werden, die für das spätere popstate-Event relevant sein könnten? Titel und URL reicht doch?

2.) Ich muss also immer auf die im stateObject gespeicherten Informationen zugreifen um den Ajax load beim popstate-Event mit den korrekten Daten erneut auszulösen.
Beim Klick auf des Browsers Zurück-Button verändert sich die URL ja (durch die in der History letzte gelistete Seite), aber die Seite wird nicht geladen (klar, weil es durch das popstate-Event geladen werden soll). Deshalb habe ich auch versucht wie in meinem ersten Code beschrieben, die URL auszulesen und anhand dessen den richtigen Inhalt zu laden. Die URL verändert sich nach dem zweiten Klick auf des Browsers Zurück-Button weiterhin, doch erhalte ich in meiner Variable keinen veränderten URL. Woran liegt das? Ich weiß, dass ich das vermutlich damit umgehen kann dass ich die URL einfach im stateObject speichere und diese URL dann beim popstate-Event auslese, doch im Prinzip sollte das doch auch funktionieren mit meinem oben genannten Beispiel?

3.) Warum unterdrückt der Browser überhaupt die Grundfunktion des Zurück-Buttons bei einem Ajax-Load? Er könnte doch einfach die in der history angegebene URL vom Client aus neu laden (wie es auch bei einer Seite ohne Ajax getan wird), statt auf ein popstate-Event zu warten?

// EDIT:
Ich möchte noch hinzufügen, dass ich gerade dein beschriebenes Beispiel testete. Beim Ajax-Load speichere ich im stateObject die URL die geladen wird um dann beim popstate-Event darauf zugreifen zu können.
Das Popstate Event wird beim Klick auf des Browsers Zurück-Button erfolgreich immer ausgeführt. Jedoch ist das stateObject nach dem zweiten Klick auf den Zurück-Button null, ebenso wie die URL in meinem ersten Post. Code:
Code:
        window.addEventListener('popstate', function (event){
            
            console.log(event.state);
            
        });
In der Konsole steht nach dem zweiten Klick auf den Zurück-Button "null"
 
Zuletzt bearbeitet:

mindraper

me[code].Java(Script)

AW: Popstate bei Ajax

moin,

1)
alles

2)
in meinem browser zumindest gibt es keine "url" eigenschaft des document objects. nur ein (window.)location.href. schonmal damit versucht?

3)
die frage solltest du dir eigentlich selbst beantworten können. ich stelle jetzt einfach einmal eine gegenfrage: wozu denn XHR ("AJAX"), wenn es ja doch das gleiche wäre wie das "normale" laden einer seite?

zum // EDIT:
ich weiß ja nicht, WIE du getestet hast. einfach "geht net" schreiben ohne code ist schlichtweg unfair. wie laufen deine XHR requests? was passiert im code drum herum?

test-html meinerseits:
HTML:
<!DOCTYPE html>
<html lang="de">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <meta name="robots" content="index,follow">
        <meta name="keywords" content="">
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0">
        <!-- /END META -->
        <title>history.pushState Test</title>
    </head>
    <body>
        <div id="log">

        </div><!-- /end log -->
        <script>
            ;(function (win, undefined) {

                var hist = win.history,
                    log = win.document.getElementById('log');

                if (hist.pushState === undefined || typeof hist.pushState !== 'function') {
                    log.innerHTML += 'Browser does not support needed methods';
                    log.innerHTML += '<br>Please use another browser';
                    return;
                }

                var stateOne = {
                        title: 'one',
                        url: '/state-one',
                        step: 'first'
                    },
                    stateTwo = {
                        title: 'two',
                        url: '/state-two',
                        step: 'second'
                    },
                    stateThree = {
                        title: 'three',
                        url: '/state-three',
                        step: 'third'
                    };

                hist.pushState(stateOne, stateOne.title, stateOne.url);
                hist.pushState(stateTwo, stateTwo.title, stateTwo.url);
                hist.pushState(stateThree, stateThree.title, stateThree.url);

                win.addEventListener('popstate', function (event) {
                    console && console.log(event.state);
                }, false);

            })(this, (void 0));
        </script>
    </body>
</html>

betätigen der vor-/zurück buttons funktioniert im test tadellos (getestet mit eingeschaltetem xampp, chrome 28/ff 21 + 22/opera 15/IE 10). ein blick in die console zeigt brav das bzw. die angeforderten event.state objects an.
 
Zuletzt bearbeitet:

sapta

Gesperrt

AW: Popstate bei Ajax

Hi und danke für deinen ausführlichen Beitrag,

ich habe mir dein Beispiel mal angesehen und ausprobiert. Es entspricht dem was ich für Resultate bekam.
Scheinbar ist das Problem vielmehr Verwirrung meinerseits ;)
Ich werde dich mal kurz darüber aufklären was mir unklar ist:
Sowohl bei deinem Beispiel als auch bei meiner Seite ist es so, dass du nur solange ein stateObject erhälst, wie du auch einen Ajax-Load ausgeführt hast. Sprich nachdem du zur Ausgangsseite zurückkommst (vor /state-one) bekommst du kein stateObject mehr im postateEvent geliefert. Das leuchtet ja auch ein, da du dort ja nichts dynamisch geladen, sondern die Seite direkt aufgerufen hast.
Wie aber gehst du mir diesem Zustand um? Du kriegst kein stateObject geliefert, d.h. du weißt nicht welchen Inhalt du laden sollst, der Browser lädt die Seite jedoch auch nicht.

Wenn du das Ganze nachspielen möchtest rufe dein Beispiel einfach mal auf und klicke den Zurück-Button bis du in der Konsole "null" erhälst. Du bist dann auf der Ausgangsseite und weißt was ich meine.

Danke und liebe Grüße :)
 

mindraper

me[code].Java(Script)

AW: Popstate bei Ajax

moin,

also: in meinem beispiel existiert keine einzige zeile die etwas mit einem XHR zu tun hat. sprich es findet auch kein "AJAX-Load" statt. :) die history API hat prinzipiell ungefähr so viel mit XHR zu tun, wie kuchen backen mit a****backen. ;)

nun zur frage, wie ich mit diesem zustand (startseite, d. h. pushState noch nie aufgerufen) umgehe: ich zeige den inhalt der startseite. fertig ist die laube. :)

alternativ: der besucher bekommt eine übersicht aller verfügbaren ressourcen angezeigt, die er ansteuern kann.

zum verständnis:

- startseite, state-object -> null
|
- ressource 1, state-object -> /res-one
|
- ressource 2, state-object -> /res-two
| |
| - ressource 2-1, state-object -> /rest-two/one
|
- ressource 3, state-object -> /res-three

wann kann das state-object nur null sein? genau, wenn der besucher auf der startseite ist. anderenfalls erhalte ich die information entweder:

a)
über die aufgerufene url, die auf eine ressource verweist (beispiel.com/res-two/one --> /res-two/one)

b)
wenn vor/zurück navigiert wird über die browser-buttons erhalte ich ein entsprechendes state-object, das auf eine ressource verweist (im beispiel stateOne, stateTwo, stateThree)

zusammengefasst:
beim aufrufen der seite checken, welche url aufgerufen wurde. zeigt die url auf eine ressource => ressource laden. zeigt die url auf keine ressource => startseite anzeigen. bewegt sich der besucher danach mit hilfe der vor/zurück buttons => via state-object arbeiten. ist das state-object === null => startseite aufrufen, analog zu url zeigt auf keine ressource.

das ist in meinem beispiel natürlich nicht enthalten. wozu auch? deine ausgangsfrage bezog sich doch, sofern ich sie richtig verstanden habe, auf die nutzung der history API, nicht auf den aufbau einer kompletten asynchron arbeitenden navigation.
 

sapta

Gesperrt

AW: Popstate bei Ajax

moin,

also: in meinem beispiel existiert keine einzige zeile die etwas mit einem XHR zu tun hat. sprich es findet auch kein "AJAX-Load" statt. :) die history API hat prinzipiell ungefähr so viel mit XHR zu tun, wie kuchen backen mit a****backen. ;)
Es geht ja nur um die Theorie. Du wirst in der Praxis selten eine URL ohne den Inhalt ändern.
nun zur frage, wie ich mit diesem zustand (startseite, d. h. pushState noch nie aufgerufen) umgehe: ich zeige den inhalt der startseite. fertig ist die laube. :)
Ja, du bist witzig :) Ich kann ja auch eine Unterseite direkt aufrufen und von dort aus 3 Seiten weiter navigieren. Wenn ich dann zurück klicke möchte ich bitte auch den Inhalt der zuerst angesteuerten Unterseite erhalten und nicht den der Startseite :) (Zum Verständnis siehe unten meine Definition zu "Startseite")
alternativ: der besucher bekommt eine übersicht aller verfügbaren ressourcen angezeigt, die er ansteuern kann.
Finde ich persönlich keine Lösung. Ich erwarte von einer Seite dass wenn ich zurück klicke ich den Inhalt angezeigt bekomme den ich davor gesehen habe. Eine Sitemap (was du ja beschreibst) gibt mir aber nur die Übersicht aller Seiten.
beim aufrufen der seite checken, welche url aufgerufen wurde. zeigt die url auf eine ressource => ressource laden. zeigt die url auf keine ressource => startseite anzeigen. bewegt sich der besucher danach mit hilfe der vor/zurück buttons => via state-object arbeiten. ist das state-object === null => startseite aufrufen, analog zu url zeigt auf keine ressource.
Ja, so sehe ich das auch. Einziger Unterschied oben genannt. Eine Startseite kann hier zweifach definiert werden:
1.) Die Start-Seite, sprich die Seite bei dem der Benutzer beginnt durch die Homepage zu navigieren
2.) Und die Starseite (die index), also die Seite auf der der Inalt gelistet wird wenn man die Domain aufruft.
Ich möchte aber nicht das Methode 2 angezeigt wird, wenn kein stateObject vorhanden ist, sondern Methode 1. Allerdings kann ich ja eben nicht ermitteln, welche Start-Seite der Benutzer hatte, da ich ja kein stateObject geliefert bekomme.
Es ist tricky. Aber unlösbar?

Frage: Wie kann ich ermitteln bei welcher Seite der Benutzer angefangen hat durch die Homepage zu navigieren, wenn ich kein stateObject im popstateEvent erhalte?
 
Zuletzt bearbeitet:

mindraper

me[code].Java(Script)

AW: Popstate bei Ajax

moin,

Ich kann ja auch eine Unterseite direkt aufrufen und von dort aus 3 Seiten weiter navigieren. Wenn ich dann zurück klicke möchte ich bitte auch den Inhalt der zuerst angesteuerten Unterseite erhalten und nicht den der Startseite

sorry, i don't get it.

a)
wenn ich eine (unter-)seite aufrufe, habe ich eine url mit eindeutigem identifizierer (bei unterseiten via url, also tld/identifizierer/der/ressource) oder die startseite/index.html (url endet nach der tld).

b)
wenn ich, egal ob start- oder unterseite, von dort aus weiter navigiere, arbeite ich doch schon mit pushState/popstate-listener. also bekomme ich logischerweise auch ein stateobject, wenn ich zurück navigiere.

Einziger Unterschied oben genannt. Eine Startseite kann hier zweifach definiert werden:
1.) Die Start-Seite, sprich die Seite bei dem der Benutzer beginnt durch die Homepage zu navigieren
2.) Und die Starseite (die index), also die Seite auf der der Inalt gelistet wird wenn man die Domain aufruft.

falsch. damit er mit IRGENDEINER seite beginnen kann, muss ein besucher spezifizieren, welche seite er sehen möchte. sprich: soll die einstiegsseite eine andere als die startseite sein, MUSS ich das irgendwie angeben. da bleibt wohl nicht viel abgesehen von der url. hast du eine url, dann hast du einen identifizierer. falls nicht, landest du unweigerlich bei 2.). bei der eingabe von google.de bekomme ich ja auch noch keine suchergebnisse gezeigt.

Ich möchte aber nicht das Methode 2 angezeigt wird, wenn kein stateObject vorhanden ist, sondern Methode 1. Allerdings kann ich ja eben nicht ermitteln, welche Start-Seite der Benutzer hatte, da ich ja kein stateObject geliefert bekomme.
Es ist tricky. Aber unlösbar?

ohne identifizierer? ja. du unterliegst einem logischen denkfehler. den kann das beste programm der welt nicht ausmerzen. woher soll deine seite denn wissen, welche daten du gerne sehen möchtest?

beispiel: du bekommst gesagt: "geh' zum metzger und hol' wurst." – weißt du jetzt genau WELCHE wurst du holen sollst?

Frage: Wie kann ich ermitteln bei welcher Seite der Benutzer angefangen hat durch die Homepage zu navigieren, wenn ich kein stateObject im popstateEvent erhalte?

über die url. oder gar nicht.
 
Bilder bitte hier hochladen und danach über das Bild-Icon (Direktlink vorher kopieren) platzieren.
Antworten auf deine Fragen:
Neues Thema erstellen

Willkommen auf PSD-Tutorials.de

In unseren Foren vernetzt du dich mit anderen Personen, um dich rund um die Themen Fotografie, Grafik, Gestaltung, Bildbearbeitung und 3D auszutauschen. Außerdem schalten wir für dich regelmäßig kostenlose Inhalte frei. Liebe Grüße senden dir die PSD-Gründer Stefan und Matthias Petri aus Waren an der Müritz. Hier erfährst du mehr über uns.

Stefan und Matthias Petri von PSD-Tutorials.de

Nächster neuer Gratisinhalt

03
Stunden
:
:
25
Minuten
:
:
19
Sekunden

Neueste Themen & Antworten

Flatrate für Tutorials, Assets, Vorlagen

Zurzeit aktive Besucher

Statistik des Forums

Themen
118.616
Beiträge
1.538.358
Mitglieder
67.536
Neuestes Mitglied
QuestionMark
Oben