Antwort an „dedlfix“ verfassen

Tach!

Ich hab mich mal rangesetzt, und eine eigene Version entworfen. (Beim Testen Browser-Konsole öffnen nicht vergessen!) Damit verbinde ich keinerlei Ansprüche. Wenn du das oder Ideen daraus übernehmen möchtest, finde ich das gut, wenn nicht, ist das auch in Ordnung.

Vorab, ich hab deine Version als Vorlage genommen abzüglich dem Formular-Handling. Dabei ist mir aufgefallen, dass sie nicht läuft, so wie sie derzeit im Wiki steht. In den Javascript-Verwendungen wird ein textElement selektiert, das nicht unter diesem Selektor im HTML-Teil steht. Sicher nur ein Aufmerksamkeitstest 😉

Anmerkungen zu meiner Version:

Es gibt ja bereits Polyfills für Dialoge, beispielsweise jenen. Trotzdem hab ich eine eigene Variante erstellt, die aber unvollständig ist. Mein Anliegen war, dass das Polyfill nur die standardisierten Teile abdeckt und keine eigene Funktionalität hinzufügt. Somit ist das Polyfill auch gegen jenes austauschbar oder kann im Falle von Chrome ganz weggelassen werden.

Im Beispiel-Code gibt es dialog.html für meine Variante und dialog-polyfill.html für das GoogleChrome-Polyfill. Der Unterschied ist eine Script-Einbindung im Head, die Funktion registerDialog und unter window.myDialog die Zeile

dialogPolyfill.registerDialog(dialog);
//vs. registerDialog(dialog);

Mein Polyfill ist unvollständig, weil showModal nicht implementiert ist sowie das Backdrop-Handling. Auch die ganzen Feinheiten für veraltete Browser sind nicht enthalten.

Wie kann man nun mit dem Polyfill bezüglich Wiki umgehen? Im Prinzip könnte man es weglassen und lediglich auf die vollständige Variante verweisen. So umfangreich, wie das dort ist, könnten wir das nicht nachbauen, ohne den Artikel zu sprengen. Als Kompromiss könnte man für Schulungszwecke das eigene Polyfill zeigen, für den Produktivbetrieb aber zu einem vollständigen raten.

In meinem Code wird das Polyfill durch die Funktion registerDialog implementiert. Zusätzlich braucht es noch das globale Escape-Handling für das Schließen des Dialogs mit Esc-Taste. Im oben verlinkten Plunkr ist das unter "Individuelle Funktionalität" angesiedelt, müsste aber zum Polyfill gerechnet werden. Andererseits reagiert zwar das Beispiel in der MDN im Chrome auf Escape (wenn der Focus im Beispielkasten ist), das GoogleChrome-Polyfill ignoriert es jedoch. Meine Ergänzung spielt jedoch problemlos mit dem GoogleChrome-Polyfill zusammen. Außerdem wäre vielleicht noch erwähnenswert, dass mein Polyfill auch <form method="dialog"> berücksichtigt.

Soweit zum Polyfill. Für unsere Belange brauchen wir jedoch noch weitergehende Funktionalität. Die wird bei mir durch window.myDialog hinzugefügt. Generell habe ich auf die bereits vorgeschlagenen Features gesetzt: Promises und Templates. (Vielleicht wird damit jetzt auch klarer, wie ich einige meiner Vorschläge gemeint hatte.)

Es gibt bei mir keine drei Dialoge, sondern nur einen, in den durch ein beliebiges Template beliebiger Inhalt eingefügt werden kann. Die drei Varianten alert, prompt und confirm sind nur Anwendungsbeispiele dieses Prinzips.

Nicht umsetzen konnte ich, dass das Escape-Schließen und das Klicken auf den Schließen-Button (d.h. alles mit close als Klasse) ins Reject läuft. Bei ordentlichem Schließen wird das Promise generell resolved. Man muss dann anhand des Rückgabewertes entscheiden, wie der Anwender den Dialog beendet hat. Das ist das value vom geklickten Button, inklusive dass der Browser selbständig bei Enter den ersten Button als geklickt simuliert.

Auch kam ich nicht völlig ohne herkömmliche Callbacks aus. Mit Promises kann man dem Verwender nur anbieten, individuell handzuhaben, was "danach" passiert. Ich brauchte jedoch auch eine Möglichkeit der individuellen Initialisierung sowie zum Bereitstellen des Ergebnisses, dazu gleich mehr. Durch Promises fällt auch weg, mit den Handler für "nach dem Schließen" irgendwas anzustellen, beispielsweise sich ihn merken zu müssen. Allerdings habe auch ich an anderer Stelle das Problem zu lösen gehabt, Eventhandler zu registrieren und das nicht mehrfach bei mehrfacher Verwendung von Dialogen. (Die entsprechende Stelle in window.myDialog ist kommentiert.)

Für das Individualisieren brauchte ich die Möglichkeit, Werte übergeben zu können. Dazu gibt es den options-Parameter. Dessen Eigenschaften sind

  • dialogSelector, der auf den Dialog verweist mit Default-Wert #mydialog
  • contentSelector, der auf das zu verwendende Template verweist
  • returnValue, als optionale Vorbelegung
  • initialize, als optionales Callback für die Initialisierung des Template-Inhalts
  • resultHandler, als optionales Callback für die Ermittlung des Ergebnisses. Ansonsten wird ein FormData-Objekt erzeugt.

Die Möglichkeit, einen Result-Handler anzugeben, brauchte ich, weil das Promise erst nach meinen Aufräumarbeiten (dialog.removeChild …) zum then() übergeht. Ein konkretes Beispiel für den Result-Handler habe ich nicht beigefügt, FormData sollte für die meisten Fälle reichen.

Durch Templates ist man zwar frei, was die Gestaltung des Dialog-Inhalts angeht. Aber manchmal möchte man auch zum Beispiel lediglich einen anderen Text anzeigen. Wie das gehen kann, habe ich im Beispiel zum Alert-Dialog eingebaut. Das Alert-Beispiel hat übrigens keinen then()-Handler, weil mein angedachter Anwendungsfall hier vom Typ "Fire and Forget" ist, ohne dass man danach noch etwas tun möchte.

Zu beachten ist generell auch, dass alles was "nach dem Schließen des Dialog" stattfinden soll, im then()-Handler stattfinden oder von diesem aufgerufen werden muss. Das ist jedoch das übliche Wesen von asynchron ablaufenden Prozessen. Der Profi jongliert dann mit den Möglichkeiten von Promises, um hier noch mehr für seinen konkreten Bedarf herauszuholen.

Ich hatte ja auch erwähnt, dass es besser ist, kleinteilige Funktionseinheiten zu bilden, statt Monsterfunktionen. Das habe ich im Polyfill meines Erachtens recht gut umgesetzt, so dass der Teil auch ohne Kommentare selbsterklärend sein sollte - bilde ich mir zumindest ein. (Siehe show - recht übersichtlich, obwohl da einiges zu tun ist.) Bei window.myDialog habe ich das nicht so umgesetzt und musste Kommentare setzen, für die bessere Nachvollziehbarkeit der Einzelteile. Das könnte man noch refaktorisieren.

Was man auch noch verbessern könnte, mehr Objektorientiertheit reinbringen, so dass im Polyfill nicht immer der Dialog an die dortigen Funktionen übergeben werden muss. Hmm, eigentlich könnte man die Übergabe auch weglassen, weil dialog ja sowieso im Closure zur Verfügung steht.

Die Internet Explorers habe ich nicht weiter beachtet. Der kann eh keine Promises, jedenfalls nicht ohne Polyfill. Ich bin der Meinung, wenn jemand unsere Dialog-Versionen im produktiven Umfeld verwenden möchte, kann er sich auch die Mühe machen, das für seinen konkreten Bedarf anzupassen. Wir wollen ja erklären und nicht einfach nur kopierfertigen Code anbieten.

dedlfix.

freiwillig, öffentlich sichtbar
freiwillig, öffentlich sichtbar
freiwillig, öffentlich sichtbar

abbrechen