Barksalot: Dialog-Box - Confirm

Hallo,

kann ich mit diesem:
https://wiki.selfhtml.org/wiki/JavaScript/Tutorials/zug%C3%A4ngliche_Dialog-Box

dieses

<a href="defekt.php?delete=<?php echo htmlspecialchars($array['avd_id']); ?>" 
   onclick="return confirm('Wirklich löschen?')">
 <img src="img/icons/delete84.png" 
      width="16" 
      height="16" 
      alt="Löschen" 
      title="Eintrag löschen">
</a>

nachbauen?`Ich möchte gerne von den hässlichen confirm boxen weg und modernere einsetzten.

Bis bald!
Bernd

  1. Lieber Barksalot,

    das dialog-Element wird wohl noch nicht genügend gut unterstützt, als dass Du es bedenkenlos einsetzen könntest.

    Liebe Grüße,

    Felix Riesterer.

    1. Hallo Felix,

      danke für den Hinweis. Kann ich auf keinen Fall nutzen, überall rot :/ Schade.
      Gibt es irgendeine alternative?

      Bis bald!
      Bernd

      1. @@Barksalot

        Kann ich auf keinen Fall nutzen, überall rot :/

        [ ] Du hast progressive enhancement verstanden.

        [ ] Du hast polyfills verstanden.

        Schade.

        [x] Du sagst es.

        LLAP 🖖

        --
        „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann
        1. Hallo Gunnar,

          es ist einfach nicht benutzbar. Kapier es einfach oder lass es. Es ist meine Meinung. Dann kann ich so eine Box auch direkt mit jQuery nachbauen.

          Bis bald!
          Bernd

          1. Dann mach es doch und troll hier nicht rum.

            1. Hallo JürgenB,

              mache ich jetzt auch!

              Bis bald!
              Bernd

    2. Servus!

      Lieber Barksalot,

      das dialog-Element wird wohl noch nicht genügend gut unterstützt, als dass Du es bedenkenlos einsetzen könntest.

      Deshalb steht im Tutorial:

      "Das dialog-Element wird leider noch nicht durchgehend unterstützt, sodass wir es zwar verwenden können, seine Funktionalität aber mit JavaScript nachbauen müssen."

      Das Element an sich wird (Wie alle unbekannten Elemente) in allen modernen Browsern dargestellt.

      Das JavaScript ändert bei Click das open-Attribut, was dann per CSS formatiert wird.

      @Barksalot Probier die Live-Beispiele im Tutorial doch mal aus!

      Herzliche Grüße

      Matthias Scharwies

      --
      "Bin ich denn der Einzigste hier, wo Deutsch kann?"
      1. Hallo Matthias,

        brauch ich nicht mehr ausprobieren, es ist nicht nutzbar.

        Bis bald!
        Bernd

        1. Hallo

          brauch ich nicht mehr ausprobieren, es ist nicht nutzbar.

          Warum?

          Tschö, Auge

          --
          Eine Kerze stand [auf dem Abort] bereit, und der Almanach des vergangenen Jahres hing an einer Schnur. Die Herausgeber kannten ihre Leser und druckten den Almanach auf weiches, dünnes Papier.
          Kleine freie Männer von Terry Pratchett
        2. Servus!

          Hallo Matthias,

          brauch ich nicht mehr ausprobieren, es ist nicht nutzbar.

          @Barksalot

          Ich habe dieses Tutorial im Juli 2016 veröffentlicht und vorher ausgiebig in allen Browsern getestet.

          Eben hatte ich (fälschlicherweise) vermutet, Du hättest einen Fehler gefunden oder aus irgendeinem anderen Grund wäre das Beispiel nicht benutzbar.

          Ich habe die Beispiele eben grad

          • auf meinen Tablet Anrdoid mit Chrome
          • Desktop FF62
          • IE11

          getestet. Auf allen Browsern sind die Beispiele funktionsfähig.

          Du müsstest halt nur ein Workaround für das ::backdrop-Pseudoelement bauen (funzt nur in Edge und Safari)

          Felix bezog sich in seiner kurzen Antwort auf das dialog-Element an sich (ohne den JS-Nachbau)

          Bis bald!
          Bernd

          Warum, Du willst doch eh nix lernen! Plenk!

          Herzliche Grüße

          Matthias Scharwies

          --
          "Bin ich denn der Einzigste hier, wo Deutsch kann?"
          1. Hallo Matthias,

            Es wird das passende HTML5-Element verwendet. Die (noch nicht vorhandene) Funktionalität wird durch JavaScript nachgebaut.

            Sobald alle gängigen Browser das Element unterstützen, kann das JS entfernt werden. Am Markup muss dann nichts mehr geändert werden.

            Das ist ja ganz geschickt.

            Bis bald!

            Jonathan

            --
            "Es gibt Besserwisser, die niemals begreifen, dass man recht haben kann und trotzdem ein Idiot ist."
            1. Servus!

              Stimmt, die Erklärung habe ich jetzt erweitert (fett ist neu):

              In HTML5 wurde das dialog-Element eingeführt, dessen Browserunterstützung für einen direkten Einsatz aber noch nicht gut genug ist. Dieser polyfill verwendet das dialog-Element in Verbindung mit konventionellen HTML-Elementen, die durch ARIA-Attribute semantisch zugeordnet werden. Die (noch nicht vorhandene) Funktionalität wird mit JavaScript nachgebaut. Bei einer durchgängigen Browserunterstützung kann das dann nicht mehr notwendige JavaScript entfernt, das HTML-Markup jedoch unverändert beibehalten werden.

              Herzliche Grüße

              Matthias Scharwies

              --
              "Bin ich denn der Einzigste hier, wo Deutsch kann?"
          2. Hallo Matthias,

            Warum, Du willst doch eh nix lernen! Plenk!

            so eine Bemerkung von einem Vorstand! SOFORT zurücktreten. Solche Menschen sind in meinen Augen in so einem Verein nicht tragbar!

            Bis bald!
            Bernd

            1. @@Barksalot

              so eine Bemerkung von einem Vorstand! SOFORT zurücktreten. Solche Menschen sind in meinen Augen in so einem Verein nicht tragbar!

              Die Entscheidung, welche Menschen in so einem Verein tragbar sind, überlass mal denen, die im Verein sind.

              Wie übrigens auch die Entscheidung, welche Menschen in diesem Forum tragbar sind. Nur mal so als Hinweis.

              LLAP 🖖

              --
              „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann
            2. Lieber Barksalot,

              Warum, Du willst doch eh nix lernen! Plenk!

              so eine Bemerkung von einem Vorstand! SOFORT zurücktreten. Solche Menschen sind in meinen Augen in so einem Verein nicht tragbar!

              aha, will nicht sein eigenes Verhalten reflektieren, sondern stänkert auch noch rum. Dir helf ich nicht mehr!

              Liebe Grüße,

              Felix Riesterer.

            3. Hallo Barksalot,

              Warum, Du willst doch eh nix lernen! Plenk!

              so eine Bemerkung von einem Vorstand! SOFORT zurücktreten. Solche Menschen sind in meinen Augen in so einem Verein nicht tragbar!

              Ich stimme Matthias hinsichtlich seiner sachlich geäußerten Kritik uneingeschränkt zu. Ich kann ebenfalls keinerlei Lernbereitschaft deinerseits erkennen. @Matthias Scharwies ist für unseren Verein durch seinen überragenden Fleiß so tragbar, wie man überhaupt nur sein kann.

              Bis demnächst
              Matthias

              --
              Pantoffeltierchen haben keine Hobbys.
          3. @@Matthias Scharwies

            Plenk!

            Netzjargon:

            • Das Wort Plenk ist eine Verballhornung eines englischen Wortes für Leerzeichen, blank.

            • Plonk ist ein lautmalerisches Wort für das Geräusch, das der „Aufschlag“ im Killfile erzeugt.

              (Wikipedia)

            LLAP 🖖

            --
            „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann
            1. Hallo,

              Netzjargon:
              Plenk/Plonk

              Ja und? Matthias meinte ganz bestimmt den kurzen Moment der Stille kurz vorm Aufschlag…

              Gruß
              Kalk

      2. Hallo Matthias,

        @Barksalot Probier die Live-Beispiele im Tutorial doch mal aus!

        schlimm, dass man die Leute noch darauf hinweisen muss 😟.

        Gruß
        Jürgen

        1. Hallo JürgenB,

          schlimm, wenn Leute glauben ich hätte da nicht schon längst drauf geklickt! Aber Hauptsache Stimmungsmache!

          Bis bald!
          Bernd

          1. Da liest sich

            brauch ich nicht mehr ausprobieren, es ist nicht nutzbar.

            aber eher wie ein „Dein Mist interessiert mich nicht“.

            1. Hallo JürgenB,

              wenn ich die Beispiele nicht angeschaut hätte, dann hätte ich wohl nicht den Link gepostet und gefragt ob ich dieses für meinen Zweck einsetzten kann, woraus keiner eingegangen ist. Lieber Stimmungsmache betreiben!

              Bis bald!
              Bernd

      3. @@Matthias Scharwies

        Deshalb steht im Tutorial:

        "Das dialog-Element wird leider noch nicht durchgehend unterstützt, sodass wir es zwar verwenden können, seine Funktionalität aber mit JavaScript nachbauen müssen."

        Müssen wir das? Ist es überhaupt sinnvoll, dass wir das nachbauen? Oder ist es nicht sinnvoller, den bei Can I use verlinkten Polyfill zu verwenden?

        Ich hab den mal in diesem Codepen eingebaut.

        Und dazu eine Frage: Warum funktioniert das

        document.querySelector('#ctrl-open-my-dialog').addEventListener('click', event => {
        	myDialogElement.showModal();
        });
        

        aber nicht das?

        document.querySelector('#ctrl-open-my-dialog').addEventListener('click', myDialogElement.showModal);
        

        LLAP 🖖

        --
        „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann
        1. Aloha ;)

          Und dazu eine Frage: Warum funktioniert das

          document.querySelector('#ctrl-open-my-dialog').addEventListener('click', event => {
          	myDialogElement.showModal();
          });
          

          aber nicht das?

          document.querySelector('#ctrl-open-my-dialog').addEventListener('click', myDialogElement.showModal);
          

          Ich habe eine begründete Vermutung: Wegen this.

          Oben wird eine Arrow Function verwendet. Arrow Functions haben die Besonderheit, dass sie keinen eigenen Ausführungskontext mit eigenem this begründen, wie das bei normalen Funktionen der Fall ist (man spricht bei Arrow Functions von lexical this).

          Deshalb musste man ja früher™️ bei Funktionen, die man mit window.setTimeout o.ä. aufgerufen hatte, immer recht umständlich das ursprünglich this mit durchreichen.

          Du definierst ja die showModal-Funktion folgendermaßen: dialog.showModal = this.showModal.bind(this);

          Das this, dass du da verwendest, ist im Fall der Arrow Function ein anderes als ohne Arrow Function. Ich bin leider nicht tief genug in der Materie drin, um dir aus dem Stegreif zu sagen, welcher Wert oben und unten jeweils in this liegt, aber es ist jedenfalls jeweils ein Anderer.


          Oben war die begründete Vermutung, jetzt kommt Spekulation.

          Ich glaube - wenn ich es richtig verstanden habe - du kannst den unteren Ansatz folgendermaßen retten:

          document.querySelector('#ctrl-open-my-dialog').addEventListener('click', myDialogElement.showModal.bind(this));
          

          Zumindest nach meinem Verständnis müsste bei dieser Variante der Kontext für this derselbe sein wie für die Arrow Function.


          Da ich in der Materie aber wie gesagt alles andere als tief drin bin: Vielleicht kann @1unitedpower da mehr sagen bzw. meine Vermutungen bestätigen oder widerlegen.

          Grüße,

          RIDER

          --
          Camping_RIDER a.k.a. Riders Flame a.k.a. Janosch Zoller
          # Twitter # Steam # YouTube # Self-Wiki # Selfcode: sh:) fo:) ch:| rl:) br:^ n4:? ie:% mo:| va:) js:) de:> zu:} fl:( ss:) ls:[
          1. Tach!

            Und dazu eine Frage: Warum funktioniert das

            document.querySelector('#ctrl-open-my-dialog').addEventListener('click', event => {
            	myDialogElement.showModal();
            });
            

            aber nicht das?

            document.querySelector('#ctrl-open-my-dialog').addEventListener('click', myDialogElement.showModal);
            

            Ich habe eine begründete Vermutung: Wegen this.

            Ja, aber die Sachlage liegt etwas anders. Es spielt keine Rolle, ob es eine Arrow Function oder eine herkömmliche ist. Es liegt aber daran, ob der Eventhandler eine Function ist oder nur eine Function-Referenz.

            myDialogElement.showModal ist eine Function-Referenz. Das heißt, die Referenz zeigt genau auf diese Methode, das Objekt davor wird nicht mehr beachtet. Und diese Function/Methode wird nun zum Event aufgerufen, als ob es eine statische Methode des Objekts wäre. Innerhalb der Function zeigt das this auf den aufrufenden Kontext. (Wo genauhin spielt keine Rolle, man kann es auf diese Weise ja nicht gebrauchen.)

            Bettet man hingegen myDialogElement.showModal() (jetzt mit Klammern) in eine Function ein, egal ob Arrow oder herkömmlich, dann wird zuerst das Object myDialogElement ermittelt und dann davon die Methode aufgerufen. Und nun zeigt das this auch auf das Objekt, so wie man das bei jeder Art Aufruf à la foo.bar() erwartet.

            Ich kann das nicht exakt erklären, aber ich hoffe, es war auch so verständlich. An dem Fall hab ich jedenfalls schon bei einer meiner Anwendung eine Weile gesessen, bevor ich das Problem erkannt hatte.

            dedlfix.

          2. @@Camping_RIDER

            Ich habe eine begründete Vermutung: Wegen this.

            Ich glaube, da muss ich dich enttäuschen.

            Dasselbe tritt auch schon hier auf:

            Geht:

            document.documentElement.addEventListener('click', () => { window.alert(); });
            

            Geht nicht:

            document.documentElement.addEventListener('click', window.alert);
            

            Fehlermeldung: TypeError: 'alert' called on an object that does not implement interface Window.

            LLAP 🖖

            --
            „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann
            1. Aloha ;)

              Ich glaube, da muss ich dich enttäuschen.

              ...und damit die Antwort von @dedlfix bestätigen.

              Dasselbe tritt auch schon hier auf:

              Geht:

              document.documentElement.addEventListener('click', () => { window.alert(); });
              

              Geht nicht:

              document.documentElement.addEventListener('click', window.alert);
              

              Fehlermeldung: TypeError: 'alert' called on an object that does not implement interface Window.

              Wie @dedlfix bereits ausführte wird beim Übergeben der Funktionsreferenz die Funktion selbst aus ihrem eigenen Kontext gerissen und an das aufrufende Objekt (in dem Fall vermutlich das Event?) angeflanscht - und die Funktion selbst funktioniert dann nur dann, wenn sie nicht von ihrem Kontext abhängt; bei showModal und alert ist aber genau das der Fall, und deshalb fehlt dann der Kontext.

              Die Lösung ist, nicht die Funktionsreferenz zu übergeben, sondern die Funktion innerhalb einer anonymen Funktion aufzurufen, wie dedlfix bereits sagte. Demnach funktioniert auch:

              document.documentElement.addEventListener('click', function(){ window.alert(); });
              

              Grüße,

              RIDER

              --
              Camping_RIDER a.k.a. Riders Flame a.k.a. Janosch Zoller
              # Twitter # Steam # YouTube # Self-Wiki # Selfcode: sh:) fo:) ch:| rl:) br:^ n4:? ie:% mo:| va:) js:) de:> zu:} fl:( ss:) ls:[
          3. Da ich in der Materie aber wie gesagt alles andere als tief drin bin: Vielleicht kann @1unitedpower da mehr sagen bzw. meine Vermutungen bestätigen oder widerlegen.

            Ich werf das Stöckchen mal @Orlok zu, der kennt sich da besser aus.

          4. Hallo Camping_RIDER

            Warum funktioniert das

            document.querySelector('#ctrl-open-my-dialog').addEventListener('click', event => {
            	myDialogElement.showModal();
            });
            

            aber nicht das?

            document.querySelector('#ctrl-open-my-dialog').addEventListener('click', myDialogElement.showModal);
            

            Ich habe eine begründete Vermutung: Wegen this.

            Die Vermutung ist richtig.

            Oben wird eine Arrow Function verwendet.

            Das spielt hier keine Rolle.

            Entscheidend ist der Kontext, in dem die Methode showModal ausgeführt wird. Im ersten Beispiel wird showModal über einen Elementausdruck als Methode des Objektes ausgeführt, das in der Konstante mit dem Namen myDialogElement hinterlegt ist. Das funktioniert, da bei dieser Form des Funktionsaufrufs die Kontextvariable this auf das Objekt zeigt, über das die Funktion referenziert wurde. In diesem Fall ist das ein Dialog-Element und ein solches wird von der Methode auch erwartet.

            Im zweiten Beispiel wird die Methode showModal selbst als Eventhandler registriert. Sie wird über einen Elementausdruck referenziert, aber nicht aufgerufen. Alles was an die Methode addEventListener übergeben wird, ist eine Referenz auf die Funktion. Die Information, über welches Objekt sie referenziert wurde, geht dabei verloren.

            Bei dem Objekt, auf dem der Eventhandler in den Beispielen oben registriert wird, handelt es sich um einen Button und nicht um ein Dialog-Element. Wenn nun im zweiten Beispiel auf den Button geklickt wird, dann wird die Funktion showModal als Eventhandler aufgerufen und dabei this mit einer Referenz auf das Objekt initialisiert, auf dem der Handler registriert wurde, also mit einer Referenz auf das Button-Element.

            Die Methode erwartet aber eine Referenz auf ein Dialog-Element.

            Deswegen geht das schief.


            Es ist hilfreich sich zu vergegenwärtigen, zu welchem Zeitpunkt eine Funktion an einen Kontext gebunden wird. Das passiert erst dann, wenn die Funktion aufgerufen wird.

            // Just member expression → `this` is unbound
            
            const method = object.method;
            
            
            // Call expression → `this` is bound to window or undefined
            
            method();
            

            In dem Beispiel oben wird eine Methode über ein Objekt referenziert, aber nicht unmittelbar aufgerufen, sondern stattdessen in einer Konstante hinterlegt. Hier findet keinerlei Bindung an einen Kontext statt. Das Objekt wird lediglich dazu verwendet, den Eigenschaftswert zu ermitteln, in diesem Fall also die Funktionsreferenz. Nach der Auswertung des Ausdrucks wird die Referenz auf das Objekt weggeworfen.

            Wird nun die Methode über die Konstante mit dem Namen method referenziert, dann ist das im Grunde nichts anderes, als wenn man eine Funktion anspricht, die unabhängig von einem Objekt für sich alleine deklariert wurde. Bei dem folgenden Aufruf wird, wie bei jedem gewöhnlichen Funktionsaufruf, entweder window oder undefined als Wert für this eingesetzt – abhängig davon, in welchem Modus das Programm ausgeführt wird.

            // Method call → `this` is bound to object
            
            const result = object.method();
            

            Anders verhält es sich, wenn es sich bei dem Ausdruck wie in diesem Beispiel um einen Methodenaufruf handelt, die Funktion also nicht nur über ein Objekt referenziert, sondern auch gleich aufgerufen wird. In diesem Fall zeigt this auf das Objekt, als dessen Eigenschaft die Funktion angesprochen wurde.

            Oben war die begründete Vermutung, jetzt kommt Spekulation.

            Ich glaube - wenn ich es richtig verstanden habe - du kannst den unteren Ansatz folgendermaßen retten:

            document.querySelector('#ctrl-open-my-dialog').addEventListener('click', myDialogElement.showModal.bind(this));
            

            Zumindest nach meinem Verständnis müsste bei dieser Variante der Kontext für this derselbe sein wie für die Arrow Function.

            Bei dieser Variante hätte this zwar tatsächlich denselben Wert wie innerhalb der Pfeilfunktion des ersten Beispiels, aber das ist leider nicht der Wert den wir brauchen. Die Registrierung der Eventhandler erfolgt hier im globalen Scope. Das bedeutet, this enthält hier eine Referenz auf das globale Objekt window. An diesen Wert bindest du nun die Methode showModal. Das ergibt offensichtlich keinen Sinn. Dein Vorschlag ist allerdings schon nahe dran.

            document.querySelector('#ctrl-open-my-dialog').addEventListener('click', myDialogElement.showModal.bind(myDialogElement));
            

            Wenn du statt this eine Referenz auf das Dialog-Element an die Methode bind übergibst, dann klappt es. In diesem Fall wird eine gebundene Funktion erzeugt, welche die Methode mit dem Dialog-Element verknüpft. Es spielt dann keine Rolle mehr, dass die gebundene Funktion als Eventhandler im Kontext des Objektes aufgerufen wird, auf dem der Handler registriert wurde: showModal wird im Kontext von myDialogElement aufgerufen.

            Viele Grüße,

            Orlok

  2. hallo

    Hallo,

    kann ich mit diesem:
    https://wiki.selfhtml.org/wiki/JavaScript/Tutorials/zug%C3%A4ngliche_Dialog-Box

    dieses

    nein.

    Wollen wir mal schauen, was System Dialogboxen leisten:

    • Der Fokus ist an der richtigen Stelle
    • Egal was ich mache, der Fokus bleibt im korrekten Kontext.
    • Die Dialogbox hat höchste Bearbeitungspriorität innerhalb eines Fensters.

    Eine Dialogbox nachbauen, heisst, den Fokus managen.

    1. @@beatovich

      Wollen wir mal schauen, was System Dialogboxen leisten:

      • Der Fokus ist an der richtigen Stelle
      • Egal was ich mache, der Fokus bleibt im korrekten Kontext.
      • Die Dialogbox hat höchste Bearbeitungspriorität innerhalb eines Fensters.

      Eine Dialogbox nachbauen, heisst, den Fokus managen.

      Du hast damit die Antwort auf meine Frage, ob es sinnvoll ist, eine Dialogbox selber nachzubauen, vorweggenommen‽

      LLAP 🖖

      --
      „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann
      1. hallo

        @@beatovich

        Wollen wir mal schauen, was System Dialogboxen leisten:

        • Der Fokus ist an der richtigen Stelle
        • Egal was ich mache, der Fokus bleibt im korrekten Kontext.
        • Die Dialogbox hat höchste Bearbeitungspriorität innerhalb eines Fensters.

        Eine Dialogbox nachbauen, heisst, den Fokus managen.

        Du hast damit die Antwort auf meine Frage, ob es sinnvoll ist, eine Dialogbox selber nachzubauen, vorweggenommen‽

        Wenn man ein Dialog-Element erstellt mit spezifischen inneren Eigenschaften (das macht Sinn) kann man durchaus System-Verhalten implementieren.

        Das letzte, was ich dazu brauche, ist ein <dialog>-element. Weder <dialog> noch role="dialog" sind magische Verhaltensinstrumente (und dem entsprechend sind auch polyfills obsolet).

        1. @@beatovich

          Wenn man ein Dialog-Element erstellt mit spezifischen inneren Eigenschaften (das macht Sinn) kann man durchaus System-Verhalten implementieren.

          Das letzte, was ich dazu brauche, ist ein <dialog>-element. Weder <dialog> noch role="dialog" sind magische Verhaltensinstrumente (und dem entsprechend sind auch polyfills obsolet).

          Ich verstehe nicht, was du damit sagen willst. Was bei mir ankommt ist:

          Es ist nicht sinnvoll, ein dialog-Element in den HTML-Standard aufzunehmen. Soll doch jeder Entwickler einen modalen Dialog selbst implementieren. Und dabei auf Tastaturbedienbarkeit und Zusammenspiel mit assistiven Technologien achten.

          Ich hoffe, ich verstehe dich falsch.

          LLAP 🖖

          --
          „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann
          1. hallo

            @@beatovich

            Wenn man ein Dialog-Element erstellt mit spezifischen inneren Eigenschaften (das macht Sinn) kann man durchaus System-Verhalten implementieren.

            Das letzte, was ich dazu brauche, ist ein <dialog>-element. Weder <dialog> noch role="dialog" sind magische Verhaltensinstrumente (und dem entsprechend sind auch polyfills obsolet).

            Ich verstehe nicht, was du damit sagen willst. Was bei mir ankommt ist:

            Es ist nicht sinnvoll, ein dialog-Element in den HTML-Standard aufzunehmen. Soll doch jeder Entwickler einen modalen Dialog selbst implementieren. Und dabei auf Tastaturbedienbarkeit und Zusammenspiel mit assistiven Technologien achten.

            Ich hoffe, ich verstehe dich falsch.

            Es ist nicht sinnvoll, elemente so zu standardisieren, dass sie die Absicht/Idee verfehlen.

            1. @@beatovich

              Es ist nicht sinnvoll, elemente so zu standardisieren, dass sie die Absicht/Idee verfehlen.

              Sicher nicht.

              Welche Absichten/Ideen findest du beim dialog-Element verfehlt?

              LLAP 🖖

              --
              „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann
              1. hallo

                @@beatovich

                Es ist nicht sinnvoll, elemente so zu standardisieren, dass sie die Absicht/Idee verfehlen.

                Sicher nicht.

                Welche Absichten/Ideen findest du beim dialog-Element verfehlt?

                Ohne mich mit den Details genau zu beschäftigen, sehe ich keine scharfe Definition bezüglich der Focus-Behandlung.

                Das Dialog-Element ist so definiert, dass es per se nur mit Javascript zu verwenden ist.

                Ein Dialog besteht in der Regel aus der äusseren Schale und dem Inhalt. Wenn ich diese Schale verlasse, darf das nur über exakt definierte Mechanismen geschehen. Die Frage ist aber, wo wird mein Fokus hinwandern, wenn ich den Dialog verlasse.

                Ein Dialog kann von verschiedenen Aktionen geöffnet werden (Ein Dialog, mehrere Aktivatoren). Ich muss wieder zum Ursprung zurück geführt werden.

                escape-Taste oder Abbruch-Button... Wir haben wieder Systemkomponenten in unserem Dialog.

                Selbstverständlich können im Dialog permanent gemachte Aktionen stattfinden. Was soll da Abbruch oder Escape? Es gibt keine bufferung.

                Die Logische Bezeichnung ist also ein Exit/Schliessen.

                Das dialog-Element ist eventuell das erste HTML Element, das ohne JS total nutzlos ist.

                Wir müssen an diesem Punkt nicht über die Implementation reden, da ja nur eine vorliegt (Chrome).

                ich bin aber gespannt, wie die Implementationsunterschiede später gefixt werden.

  3. Lieber Barksalot,

    ergänzend noch dieser Gedanke:

    // hier hält der Browser alles an, bis das Fenster wieder weg ist:
    var a = window.confirm("Ist das so OK?");
    
    // danach erst kann es hier weiter gehen (was wiederum den Browser anhält):
    alert("Es ist also " + (a ? "" : "so nicht ") + "OK.");
    

    Mittlerweile sollte sich herumgesprochen haben, dass sowohl confirm, als auch alert oder prompt aus heutiger Sicht sehr problematische Methoden sind, da sie jegliche Ausführung von JavaScript so lange blockieren, bis ihre modalen Dialoge vom User in irgendeiner Weise bestätigt wurden. Das ist vor allem für asynchrone Requests ein Problem, die dann im Hintergrund ebenfalls angehalten werden.

    Wie geht es besser? Kann man "einfach" ein solches Dialogfenster nachbilden und fertig? Nein! Denn wenn man das Dialogfeld mit JavaScript "gebastelt" hat (z.B. mit dem dialog-Element), dann braucht es irgendeinen Trick, wie man die Wiederaufnahme der Weiterverarbeitung durch JavaScript anwirft.

    Betrachten wir das (vereinfachte) obige Beispiel erneut:

    var a = confirm("OK?");
    alert(a ? "Ja." : "Nein!");
    

    Wie wir sehen, ist der Programmfluss dieser:

    1. Eingabe: Variable a mit dem Rückgabewert von window.confirm befüllen
    2. Verarbeitung: Basierend auf a entweder ein "Ja." oder ein "Nein!" ausgeben

    Das sieht sehr einleuchtend und bequem aus, da wir unser Programm genau so schreiben können, wie wir uns dessen Ablauf vorstellen.

    Wenn wir aber auf diese blockierenden Methoden verzichten wollen, wird der Programm-Ablauf ein wesentlich komplexerer, weil nicht mehr linear. Wir brauchen im Grunde drei Programme:

    1. Vorbereitung: Dialog bauen
    2. Eingabe: Dialog auswerten
    3. Verarbeitung: "OK" oder "Nicht OK" ausgeben

    Das könnte (wiederum stark vereinfacht) so aussehen:

    /**
     * process user input
     *
     * @param bool
     */
    function okOrNot (userChoice) {
      if (userChoice) {
        // OK
        document.body.appendChild(
          // <p>
          document.createElement("p").appendChild(
            document.createTextNode("OK")
          )
        );
      } else {
        // NOT OK!
        document.body.appendChild(
          // <p>
          document.createElement("p").appendChild(
            document.createTextNode("Nicht OK")
          )
        // <p class="warning">
        ).setAttribute("class", "warning");
      }
    }
    
    /**
     * create GUI for user interaction
     *
     * @param string
     */
    function myConfirm (question) {
      // build my dialog
      const diag = {};
    
      // prevent any further event action
      diag.stopEvent = function (event) {
        event.preventDefault();
        event.stopPropagation();
        return false;
      };
    
      // hide dialog
      diag.hide = function () {
        // 1. possibility: manipulate style object
        diag.formElement.style.display = "none";
        // 2. possibility: remove <form> element from document
        diag.formElement.parentNode.removeChild(diag.formElement);
        // 3. possibility with suitable CSS like form[data-disabled] {display:none;}
        diag.formElement.setAttribute("data-disabled", "disabled");
      };
    
      diag.formElement = document.createElement("form");
    
      // the question
      diag.formElement.appendChild(
        // <p>
        document.createElement("p").appendChild(
          document.createTextNode(question)
        )
      );
    
      // add OK button <button name="ok">
      ...
    
      // add cancel button <button name="cancel">
      ...
    
      // capture form submission event
      diag.formElement.addEventListener("submit", function (event) {
        // which button did the user press?
        okOrNot(event.target == diag.form.querySelector('button[name="ok"]');
    
        // no more standard form action
        return diag.stopEvent(event);
      });
    
      // add escape button functionality
      diag.formElement.addEventListener("keyDown", function (event) {
        // escape key has keyCode 27
        if (event.keyCode == 27) {
          okOrNot(false);
          return diag.stopEvent(event);
        }
      });
    }
    

    Zum Verständnis: Das zweite Programm aus obiger Liste (Eingabe: Dialog auswerten) befindet sich im diag-Objekt eingebaut.

    Wie man sehen kann, ist plötzlich sehr viel Aufwand notwendig geworden, da das Anbieten des Dialogs nicht in demselben Programm-Abschnitt geschieht, wie die Auswertung der Nutzeraktion mit demselben. Daher ist die Antwort auf die ursprüngliche Frage "kann ich mit diesem [Tutorial für zugängliche Dialog-Box] dieses [window.confirm-Funktionalität] nachbauen?" ein klares "Nein, nicht ohne weitere Anstrengungen!". Und dabei habe ich die Aspekte der Zugänglichkeit, die im von Dir genannten Artikel aufgeführt wurden, noch nicht berücksichtigt!

    Liebe Grüße,

    Felix Riesterer.

    1. Tach!

      Wie geht es besser? Kann man "einfach" ein solches Dialogfenster nachbilden und fertig? Nein! Denn wenn man das Dialogfeld mit JavaScript "gebastelt" hat (z.B. mit dem dialog-Element), dann braucht es irgendeinen Trick, wie man die Wiederaufnahme der Weiterverarbeitung durch JavaScript anwirft.

      [... confirm()-Variante ...]

      Wenn wir aber auf diese blockierenden Methoden verzichten wollen, wird der Programm-Ablauf ein wesentlich komplexerer, weil nicht mehr linear. Wir brauchen im Grunde drei Programme:

      1. Vorbereitung: Dialog bauen
      2. Eingabe: Dialog auswerten
      3. Verarbeitung: "OK" oder "Nicht OK" ausgeben

      Wie man sehen kann, ist plötzlich sehr viel Aufwand notwendig geworden, da das Anbieten des Dialogs nicht in demselben Programm-Abschnitt geschieht, wie die Auswertung der Nutzeraktion mit demselben.

      Das ist auch nicht weiter tragisch, denn das Dialog-Handling an sich kann man besser so allgemein halten, dass es wiederverwendbar ist. Damit befindet sich dessen Code sowieso an anderer Stelle als die Verwendung.

      Daher ist die Antwort auf die ursprüngliche Frage "kann ich mit diesem [Tutorial für zugängliche Dialog-Box] dieses [window.confirm-Funktionalität] nachbauen?" ein klares "Nein, nicht ohne weitere Anstrengungen!".

      Zumindest kann man mit modernem Javascript und der Verwendung eines Promise die Verwendung wieder so einfach gestalten, wie es bei confirm() der Fall war. (Statt eines Promise könnte man auch einen herkömmlichen Callback nehmen.) Damit (auch mit der Callback-Variante) wird der Dialog universeller verwendbar, weil die feste Koppung zu okOrNot aufgehoben ist.

      Meine Version sähe so aus:

      function myConfirm(question) {
          return new Promise((resolve, reject) => {
              const diag = {
                  formElement: document.createElement("form"),
      
                  stopEvent: (event) => {
                      event.preventDefault();
                      event.stopPropagation();
                  },
      
                  hide: () => {
                      diag.formElement.parentNode.removeChild(diag.formElement);
                  }
              };
      
              // the question
              diag.formElement.appendChild(
                  // <p>
                  document.createElement("p").appendChild(
                      document.createTextNode(question)
                  )
              );
      
              // add OK button <button name="ok">
              //...
      
              // add cancel button <button name="cancel">
              //...
      
              // capture form submission event
              diag.formElement.addEventListener("submit", function (event) {
                  // no more standard form action
                  diag.stopEvent(event);
      
                  diag.hide();
      
                  // which button did the user press?
                  resolve(event.target == diag.formElement.querySelector('button[name="ok"]'));
              });
      
              // add escape button functionality
              diag.formElement.addEventListener("keyDown", function (event) {
                  // escape key has keyCode 27
                  if (event.keyCode == 27) {
                      diag.stopEvent(event);
                      diag.hide();
                      resolve(false);
                  }
              });
      
          });
      }
      
      // ==========
      // Verwendung
      // ==========
      
      myConfirm("Wollen Sie wirklich ...?")
          .then(result => {
              const el = result ? 'p' : '<p class="warning">';
              const text = result ? 'OK' : 'Nicht OK';
      
              document.body.appendChild(
                  // <p>
                  document.createElement(el).appendChild(
                      document.createTextNode(text)
                  )
              );
          });
      

      Ich habe auch einige Stellen gekürzt, damit man sich nicht so sehr wiederholt. Vor allem im Teil 3. Auch im hide() kann man sich das Stylen sparen, wenn das Element sowieso aus dem DOM entfernt wird.

      Da ist auch noch mehr Optimierungspotential drin. Zum Beispiel hab ich nicht weiter geschaut, inwieweit man statt diag this nehmen kann. stopEvent() kann auch eine Standalone-Funktion sein, weil sie nicht auf das Dinge des diag-Objekts zugreift. Jedenfalls konnte da das return false raus, das ist bereits durch preventDefault() abgedeckt. Dann muss das auch nicht mehr an letzter Stelle im Eventhandler stehen, was durch das Promise(oder Callback)-Handling sowieso ungünstig wäre.

      Was übrigens noch fehlt ist das Einbetten des diag.formElement ins DOM. Aber das sollte ja nur das Prinzip zeigen und nicht als fertige Copy&Paste-Vorlage dienen.

      dedlfix.

      1. Lieber dedlfix,

        Zumindest kann man mit modernem Javascript und der Verwendung eines Promise die Verwendung wieder so einfach gestalten, wie es bei confirm() der Fall war.

        gilt nicht für alle derzeit genutzten Browser. Inwiefern das vernachlässigbar ist, hängt mit dem beabsichtigten Nutzerkreis zusammen. Jedenfalls ist der IE raus, was die Android-Browser angeht, so weiß ich nicht ab welchem Android "Chrome for Android" das unterstützt.

        (Statt eines Promise könnte man auch einen herkömmlichen Callback nehmen.) Damit (auch mit der Callback-Variante) wird der Dialog universeller verwendbar, weil die feste Koppung zu okOrNot aufgehoben ist.

        Richtig.

        Liebe Grüße,

        Felix Riesterer.