Linuchs: Master-Slave Problem Liederbuch: Master-Seite soll nicht neu geladen werden

problematische Seite

Moin,

ich bastle an folgender Anwendung:

Beliebig viele Personen eines Chores laden das Liederbuch online auf ihr Tablet.

http://osmer.de/musik/liedtexte/testchor.htm

Der Dirigent lädt es sich mit dem Parameter ?master=1 und kann auf einen Titel klicken, dessen Nummer per Ajax an den Server geschickt und in einer Datei gespeichert wird.

Alle Liederbücher (Slaves) fragen im 10-sec-Takt per Ajax den Server nach der aktuellen Nummer. Wenn sie sich von der zwischengespeicherten unterscheidet, wird das Liederbuch auf diesen Titel positioniert.

Problem: Wenn Master die neue Nummer abschickt, wird sein Liederbuch neu geladen. Warum?

testchor.htm:

...
<a class=regie onclick="javascript:regie_sende( 'text','#lied_01' )" title="Nr. 1 an Slaves senden"></a>
...

Statt <a> habe ich es auch mit <div> versucht.

Das request-Objekt wird in standard.js eingerichtet.

regie.js:

function regie_sende ( art, nr ) {
  // art  = text / noten
  // nr   = #lied_09
  if ( typeof request == "undefined" ) makeRequestObject( 'regie_sende' );  // in css/standard.js wird Objekt namens "request" erzeugt
  var url = "http://osmer.de/musik/ajax_regie.php?art=" +art +"&nr=" +encodeURIComponent(nr);
  request.open('post', url, true);              // Request öffnen
  request.send(null);                           // Request senden
//request.onreadystatechange = regie_empfange;  // Request auswerten
//alert( "["+url+"]" );
  alert( "["+location.href+"]" );
}

function regie_abrufen () {
  // diese Funktion wird alle 10 sec aufgerufen von 2018_shanty_projektchor_a4.htm
  if ( typeof request == "undefined" ) makeRequestObject( 'regie_sende' );  // in css/standard.js wird Objekt namens "request" erzeugt
  var url = "http://osmer.de/musik/ajax_regie.php?art=abrufen";
  request.open('post', url, true);              // Request öffnen
  request.send(null);                           // Request senden
  request.onreadystatechange = regie_empfange;  // Request auswerten
//alert( "["+url+"]" );
}

var regie_anker = '';
function regie_empfange () {
  // http://www.w3schools.com/ajax/ajax_xmlhttprequest_onreadystatechange.asp
  // The onreadystatechange event is triggered every time the readyState changes.
  if ( request.readyState == 4 && request.status == 200 ) {
//  alert( "[" + request.responseText + "]" );
    if ( regie_anker != request.responseText ) {
      regie_anker = request.responseText;
      location.href = regie_anker;   // z.B. #lied_06
    }
  }
}

Die aktuell gespeichert Nummer kann abgerufen werden mit

http://osmer.de/musik/ajax_regie.php?art=abrufen

(Damit sich mehrere Chöre nicht "beißen", muss ich noch eine Projekt-Bezeichnung einführen)

Gruß, Linuchs

  1. problematische Seite

    @@Linuchs

    Alle Liederbücher (Slaves) fragen im 10-sec-Takt per Ajax den Server nach der aktuellen Nummer.

    Warum das denn? Stattdessen wären server-sent events angebracht. [MDN, Dr. Web, html5rocks, w3schools]

    ...
    <a class=regie onclick="javascript:regie_sende( 'text','#lied_01' )" title="Nr. 1 an Slaves senden"></a>
    ...
    

    Statt <a> habe ich es auch mit <div> versucht.

    Nein, das ist grundverkehrt.

    Niemals auf click-Events von nicht-interaktiven Elementen (wie div) lauschen (bzw. nicht-interaktiven Elemente als target bei event delegation verwenden), damit die Anwendung allgemein bedienbar ist.

    Nicht-interaktive Elemente sind nicht in der Tab-Reihenfolge und prinzipiell nicht anclickbar. Sie mögen für einen Teil der Nutzer bedienbar sein, für einen anderen Teil aber unbedienbar.

    Das a-Element ohne href-Attribut ist aber auch kein interaktives Element. a-Elemente sind für Links da. Wenn kein Link, dann kein a-Element. Für Aktionen sind buttons zu verwenden.

    LLAP 🖖

    --
    “When UX doesn’t consider all users, shouldn’t it be known as ‘Some User Experience’ or... SUX? #a11y” —Billy Gregory
    1. problematische Seite

      Hallo Gunnar,

      Warum das denn? Stattdessen wären server-sent events angebracht. [MDN, Dr. Web, html5rocks, w3schools]

      Danke für den Tipp. Jetzt ist die Zeit, dass ich mich da einarbeite.

      Für Aktionen sind buttons zu verwenden.

      Okay.

      Gruß, Linuchs

    2. problematische Seite

      in dem Beispiel w3schools.com verstehe ich nicht, wie die Datei demo_sse.php aktiviert wird.

      Die schickt ungefähr alle 5 sec eine Zeitangabe. Aber wieso?

      1. problematische Seite

        Hallo Linuchs,

        wenn ich die Antwort von Licson hier richtig verstanden habe, dann ist das mal wieder ein W3Fools Beispiel. Wenn das PHP Script nicht weiterläuft und bspw. in eine Schleife mit einem SLEEP darin geht, versucht das JavaScript alle paar Sekunden, die Event-Source neu zu verbinden. Dadurch wird das PHP Script einfach neu gestartet. Dieser Retry führt zu der Intervall-Abfrage, die man im Beispiel sieht. Durch diesen Reconnect entsteht aber kein SSE, sondern ein hinter der EventSource verstecktes Polling.

        Bei MDN gibt's ein Beispiel mit einer sleep-Schleife. Das ist schon eher das Richtige; der Serverprozess muss in dieser Schleife die DB abfragen und bei Änderungen das Event an den Client senden. Aber Polling ist das immer noch, nur nicht mehr vom Browser zum Server.

        Eine vernünftige Implementierung muss aber noch anders aussehen, da braucht man entweder eine Signalisierung zwischen den PHP-Prozessen (Semaphore, Shared Memory, Named Pipes) oder aber EINEN Prozess, der alle SSE Requeste handhabt und der bei einem Ping des Masters ein Event an alle Slaves schickt. Letzteres dürfte mit PHP nicht gehen, es sei denn, du findest eine schlaue SSE Lib die mit Socket-IO herummacht und das selbst steuert. Node.js dürfte hier eher das Werkzeug der Wahl sein.

        Das ist alles nicht trivial zu bauen und eine polling loop auf die DB oder ein File ist bei einem Chor mit nicht all zu vielen Sängern sicherlich billiger und einfacher.

        Rolf

        --
        sumpsi - posui - clusi
  2. problematische Seite

    Lieber Linuchs,

    <a class=regie onclick="javascript:regie_sende( 'text','#lied_01' )" title="Nr. 1 an Slaves senden"></a>
    

    das "javascript:" benötigst Du nur im href-Attribut. Wenn Du allen Ernstes das onclick-Attribut verwendest, dann musst Du dafür sorgen, dass der Rückgabewert der aufgerufenen Funktion (nein, nicht regie_sende, sondern HTMLElementObject.onclick!) ein false ergibt. Das geht z.B. so:

    <a onclick="regie_sende( 'text','#lied_01' ); return false;">
    

    Wenn jetzt regie_sende selbst ein return false; am Ende hat, kannst Du das sogar verkürzt notieren:

    <a onclick="return regie_sende( 'text','#lied_01' )">
    

    Damit sollte der "Seitenwechsel" nach dem Anklicken vermieden werden.

    ABER: So solltest Du es wirklich nicht machen. Besser wäre es, Dein class=regie" dafür zu nutzen, einen passenden Eventhandler per JavaScript zu vergeben. Vielleicht kannst Du den Hash #lied_01 aus dem title-Attribut herauslösen, oder Du vergibst dem a-Element ein data-*-Attribut, in dem der Hash steht:

    <a class="regie" data-sende="#lied_01">
    

    Wenn die Seite fertig geladen hat, suchst Du per JavaScript einfach alle a-Elemente mit der Klasse "regie":

    document.addEventListener("DOMContentLoaded", function () {
    
      // alle passenden Links finden
      var sender = document.querySelectorAll("a.regie");
    
      // alle gefundenen Links präparieren
      sender.forEach(function (a) {
        // dynamisches onclick vergeben
        a.addEventListener("click", function (event) {
          // Variable a ist hier bekannt (closure)
          return regie_sende("text", a.dataset.sende);
      });
    });
    

    Ich habe obigen Code natürlich nicht geprüft, aber Du wirst verstehen, was ich meine, um es im Fehlerfalle selbst korrigieren zu können.

    Liebe Grüße,

    Felix Riesterer.

    1. problematische Seite

      Hallo!

      Bitte mal für Doofe wie mich klarstellen, was [außer dem fehlenden Hinweis auf die Verwendung von <button>] an den Ausführungen von Felix falsch sein soll.

      1. problematische Seite

        @@Regina Schaukrug

        Bitte mal für Doofe wie mich klarstellen, was an den Ausführungen von Felix falsch sein soll.

        1. Der Hinweis, dass es <a href="javascript:…"> überhaupt gibt. Das wäre noch verzeihlich.

        2. Ein a-Element ohne href-Attribut als Bedienelement vorzusehen. Felix sollte es besser wissen. Der Fehler gibt sofort einen Minuspunkt. Zumal ich das in diesem Thread schon zum wiederholten Male sagte.

        LLAP 🖖

        --
        “When UX doesn’t consider all users, shouldn’t it be known as ‘Some User Experience’ or... SUX? #a11y” —Billy Gregory
        1. problematische Seite

          Lieber Gunnar,

          1. Ein a-Element ohne href-Attribut als Bedienelement vorzusehen. Felix sollte es besser wissen. Der Fehler gibt sofort einen Minuspunkt. Zumal ich das in diesem Thread schon zum wiederholten Male sagte.

          warum sollte ich wiederholen, was Du schon wiederholt hast? Immerhin konnte ich exakt den Fehler (Seite lädt neu) auf die technische Ursache reduzieren. Ohne Missioniererei. Letztere ist Deine Sache. Da darfst Du Dich darin erschöpfen. Das machst Du doch hier am liebsten, wozu konkurrieren wollen...

          Liebe Grüße,

          Felix Riesterer.

          1. problematische Seite

            @@Felix Riesterer

            warum sollte ich wiederholen, was Du schon wiederholt hast?

            Du solltest nicht wiederholen, was ich schon sagte. Du solltest nicht den Fehler von Linuchs wiederholen.

            Das war eigentlich nicht schwer zu verstehen. Das wolltest du absichtlich missverstehen?

            Ohne Missioniererei. Letztere ist Deine Sache.

            Dass du es als „Missioniererei“ abtust, wenn ich grundlegende Fehler anspreche (und wenn diese immer wieder gemacht werden, dann halt immer wieder), das sagt wohl mehr über dich als über mich.

            Da darfst Du Dich darin erschöpfen. Das machst Du doch hier am liebsten, wozu konkurrieren wollen...

            Die dümmliche Polemik kannst du dir sonstwohin stecken.

            LLAP 🖖

            --
            “When UX doesn’t consider all users, shouldn’t it be known as ‘Some User Experience’ or... SUX? #a11y” —Billy Gregory
            1. problematische Seite

              Lieber Gunnar,

              Die dümmliche Polemik kannst du dir sonstwohin stecken.

              leider konntest Du Linuchs mit seinem technisches Problem nicht helfen. Du hast "Fehler" (hinsichtlich Usability-Gral) angemahnt, deren Behebung bei seinem Problem nicht im mindesten geholfen haben. Inwiefern ist meine Polemik also unangebracht?

              Liebe Grüße,

              Felix Riesterer.

              1. problematische Seite

                @@Felix Riesterer

                leider konntest Du Linuchs mit seinem technisches Problem nicht helfen.

                Der Hinweis, nicht alle 10 Sekunden zu pullen, sondern server-sent events einzusetzen, war in deinen Augen keine Hilfe. Kannst du dafür einen triftigen Grund angeben?

                Du hast "Fehler" (hinsichtlich Usability-Gral) angemahnt

                1. Ein Fehler ist kein „Fehler“.

                2. Ein Webseite so zu bauen, dass sie bedienbar ist, ist nicht der heilige Gral, sondern sollte Normalität sein.

                LLAP 🖖

                --
                “When UX doesn’t consider all users, shouldn’t it be known as ‘Some User Experience’ or... SUX? #a11y” —Billy Gregory
                1. problematische Seite

                  Lieber Gunnar,

                  Der Hinweis, nicht alle 10 Sekunden zu pullen, sondern server-sent events einzusetzen, war in deinen Augen keine Hilfe. Kannst du dafür einen triftigen Grund angeben?

                  Du wolltest das ungelöste Problem des OP mit einem neuen, für den OP ebenso ungelösten, ersetzen.

                  1. Ein Webseite so zu bauen, dass sie bedienbar ist, ist nicht der heilige Gral, sondern sollte Normalität sein.

                  Der OP baut keine Website. Das hat er klar und deutlich formuliert. Er baut ein Tool für einen sehr speziellen Anwendungsfall, für den er sich der Webtechniken bedient. Das ist nicht das selbe.

                  Liebe Grüße,

                  Felix Riesterer.

                  1. problematische Seite

                    @@Felix Riesterer

                    Du wolltest das ungelöste Problem des OP mit einem neuen, für den OP ebenso ungelösten, ersetzen.

                    Ich wollte ihn auf einen anderen Lösungsweg hinweisen. Was ist daran verkehrt?

                    1. Ein Webseite so zu bauen, dass sie bedienbar ist, ist nicht der heilige Gral, sondern sollte Normalität sein.

                    Der OP baut keine Website. Das hat er klar und deutlich formuliert. Er baut ein Tool für einen sehr speziellen Anwendungsfall, für den er sich der Webtechniken bedient. Das ist nicht das selbe.

                    Ja und nein.

                    Auch einen sehr speziellen Anwendungsfall so zu bauen, dass er bedienbar ist, sollte Normalität sein.

                    Da zu unterscheiden ist unsinnig – aus mehreren Gründen:

                    1. Für den Entwickler wäre es unsinnig, zwei Regelsätze zu erlernen: einen für Webseiten, einen für sehr spezielle Anwendungsfälle. Zumal es da 50 Grautöne dazwischen gibt.

                      Es gibt einen Regelsatz, wie man Webtechnologien verwendet, egal ob man eine Webseite oder einen sehr speziellen Anwendungsfall baut.

                    2. Für den Nutzer ist es unsinnig, wenn der Entwickler Webtechnologien nicht standardgemäß verwendet.

                      Das würde in diesem Fall bedeuten, dass jemand, der die Anwendung nicht mit der Maus (o.ä. Zeigerdingens) bedient, sondern per Tastatur (Fußschalter, … was auch immer), gesagt kriegt: Nee, du darfst nicht bei uns im Chor mitmachen. Der Entwickler hat ein a-Element ohne href-Attribut verwendet – deshalb können wir dich hier nicht gebrauchen. Verschwinde!

                      Merkste selber, wie unsinnig die Unterscheidung Webseite vs. spezieller Anwendungsfall an dieser Stelle ist?

                    3. Hier im Forum lesen noch andere mit; die übernehmen Beispiele für ihre Webseiten. Daher ist es geboten, jeden Fehler, der zu Unbenutzbarkeit führt, zu korrigieren.

                      Und solche Fehler als Antwortender nicht zu begehen.

                    LLAP 🖖

                    --
                    “When UX doesn’t consider all users, shouldn’t it be known as ‘Some User Experience’ or... SUX? #a11y” —Billy Gregory
                    1. problematische Seite

                      Lieber Gunnar,

                      wie Du immer schön den Kontext änderst...

                      Ich wollte ihn auf einen anderen Lösungsweg hinweisen. Was ist daran verkehrt?

                      Wir hatten es nicht von verkehrt, sondern von "war in Deinen Augen keine Hilfe". Und Dein anderer Lösungsweg war eben keine Hilfe, da er das technische Problem nicht löst. Sicher hast Du Rolfs Antwort gelesen. Sie endet mit "nicht trivial". Also ist der von Dir vorgeschlagene Lösungsweg definitiv keine Lösung des ursprünglichen technischen Problems (Seite lädt neu) und verkompliziert obendrein die Herangehensweise bis ins Unlösbare, da die dafür notwendige Infrastruktur nicht verfügbar ist. Insofern ist Dein Hinweis keine Hilfe.

                      Aber das musst Du alles nicht einsehen, denn Du missionierst.

                      Auch einen sehr speziellen Anwendungsfall so zu bauen, dass er bedienbar ist, sollte Normalität sein.

                      Für die endliche und klar definierte Zielgruppe ist er das. Auch wenn Du das aus Prinzipien nicht einsehen magst.

                      Es gibt *einen* Regelsatz, wie man Webtechnologien verwendet, egal ob man eine Webseite oder einen sehr speziellen Anwendungsfall baut.
                      

                      Das ist reines Missionieren. Hauptsache wir sehen alles aus Deiner Perspektive, egal ob es in diesem, wie Du zumindest in Deiner Formulierung zugibst, speziellen Anwendungsfall passt.

                      1. Für den Nutzer ist es unsinnig, wenn der Entwickler Webtechnologien nicht standardgemäß verwendet.

                      Dem Nutzer ist das völlig gleichgültig. Er klickt/tatscht auf "irgendwas". Und dass dieses Irgendwas am besten ein Button sein sollte, hast Du ja schon geschrieben.

                      Das würde in diesem Fall bedeuten, dass jemand, der die Anwendung nicht mit der Maus (o.ä. Zeigerdingens) bedient, sondern per Tastatur (Fußschalter, … was auch immer), gesagt kriegt: Nee, du darfst nicht bei uns im Chor mitmachen.
                      

                      Du willst also dem OP erklären, wie es um seinen Chor bestellt ist? Im Ernst?

                      Der Entwickler hat [...] – deshalb können wir dich hier nicht gebrauchen. Verschwinde! [...] Merkste selber, wie unsinnig die Unterscheidung Webseite vs. spezieller Anwendungsfall an dieser Stelle ist?

                      Ich merke nur das übliche von Dir. Leider.

                      Liebe Grüße,

                      Felix Riesterer.

                      1. problematische Seite

                        @@Felix Riesterer

                        Du gibst den üblichen Bullshit ab. Ich hab die Schnauze voll.

                        LLAP 🖖

                        --
                        “When UX doesn’t consider all users, shouldn’t it be known as ‘Some User Experience’ or... SUX? #a11y” —Billy Gregory
  3. problematische Seite

    Problem: Wenn Master die neue Nummer abschickt, wird sein Liederbuch neu geladen. Warum?

    Danke für den Hinweis von Felix. return false; hat geholfen.

    Ich habe auch Buttons genommen statt <a>.

    Linuchs