バニラJSでシンプルな確認モードを作成する


今まで使ってwindow.confirm() 前に?それはあなたが本当に彼らがやっていることを確認するユーザーが欲しいときに非常に便利です顕著な方法です.しかし、あなたはそれをスタイリングしようとしたことがありますか?と同じようにwindow.alert() それは不可能ですので、我々は独自の確認モードを作成する必要があります.お見せしましょう!

何を解決する
第一に、我々が解決しようとしているものをマップするのは役に立ちます.私たちのモーダルが3つのことをすることが重要です.
  • ユーザが答えるべき質問をする(例えば、ユーザアカウントを本当に削除しますか?)
  • ユーザーは'はい'を聞かせて
  • ユーザーに「いいえ」と言いましょう
  • また、開発者向け.window.confirm() ので、使いやすいです.我々はそれを行うよりも我々のカスタムの確認を使用して開発者のためにそれをはるかに困難にしたくないconst theyAreSure = window.confirm('Are you sure'); .
    ネイティブ・モーダルが伴うもう一つのものは、モーダル自体です.私たちは、私たちのコンポーネントを使用してDEVsに何かを確認するようにユーザーに尋ねる必要があるたびにマークアップをたくさん作成する必要がありません.
    最終的には
  • 使いやすい
  • ユーザーが「はい」と言う前に、どんなコードも実行しません

  • ハウツーとスタイル

    マークアップ
    このチュートリアルでは、畳み込みマークアップを指定することは重要ではありませんので、この単純なコードをHTMLベースとして使用しましょう.
    <dialog class="confirm-dialog">
      <div class="confirm-dialog-question">Do you really want to delete your user account?</div>
      <div class="confirm-dialog-button-group">
        <button class="confirm-dialog-button confirm-dialog-button--false" type="button">Noo</button>
        <button class="confirm-dialog-button confirm-dialog-button--true" type="button">Yes!</button>
      </div>
    </dialog>
    
    あなたが不慣れであるならば<dialog> エレメントチェックアウトMDN's documentation about it ! 短い紹介として、Chrome , Firefox , Operaでサポートされているネイティブの要素です(there is a polyfill as well ) を使用してモードを表示するにはshowModal() メソッド
    function createDialog() {
      const dialog = document.createElement('dialog');
      dialog.textContent = '✨✨✨';
    
      document.body.appendChild(dialog);
    
      dialog.showModal();
    }
    

    ジャバスクリプト
    を利用してPromise API 一緒に async / await , 我々は以前にリストしたものの2つを解決することができます:私たちはコードを使いやすくすることができます、そして、私たちは、いつ(かどうか)、実際にDBですべてのユーザーを削除するコードを実行するための信号を待つことができます.
    最終的に、コンポーネントの使用は次のようになります.
    async function deleteUsers() {
      const dialog = new ConfirmModal({ 
        questionText: 'Are you sure you want to delete every user?' 
      });
    
      const deleteEveryUser = await dialog.confirm();
      if (deleteEveryUser) {
        // ...
      }
    }
    
    これは簡単にコンポーネントを使用するが、これは動作しますか?
    ジャバスクリプトawait 待っているという約束が解決されるか拒否されるまでコード実行を停止します.約束はイベントによって引き起こされる関数によって解決することができます、そして、これは我々がどのように我々のコードを構成するかです.新しい約束を作成するとき、我々は2つのボタンにイベントリスナーを加えます、そして、ボタンのどちらがクリックされるかによってtrue or false - ユーザーが確認するかどうか.

    解決
    の作成から始めましょうConfirmDialog コンポーネントのクラスです.コンストラクタには三つのことが必要です.
  • 質問テキスト
  • 'はい'ボタンのテキスト
  • ' no 'ボタンのテキスト
  • class ConfirmDialog {
      constructor({
        questionText,
        trueButtonText,
        falseButtonText
      }) {
        this.questionText = questionText || 'Are you sure?';
        this.trueButtonText = trueButtonText || 'Yes';
        this.falseButtonText = falseButtonText || 'No';
    
        this.dialog = undefined;
        this.trueButton = undefined;
        this.falseButton = undefined;
        this.parent = document.body;
    
        this._createDialog();
        this._appendDialog();
      }
    }
    
    私は、1つのメソッドを作成しました<dialog> 要素とその子<body> , そして、体からそれを取り除いて、それから我々を削除する1つConfirmDialog オブジェクト.このように見えます.
      _createDialog() {
        this.dialog = document.createElement("dialog");
        this.dialog.classList.add("confirm-dialog");
    
        const question = document.createElement("div");
        question.textContent = this.questionText;
        question.classList.add("confirm-dialog-question");
        this.dialog.appendChild(question);
    
        const buttonGroup = document.createElement("div");
        buttonGroup.classList.add("confirm-dialog-button-group");
        this.dialog.appendChild(buttonGroup);
    
        this.falseButton = document.createElement("button");
        this.falseButton.classList.add(
          "confirm-dialog-button",
          "confirm-dialog-button--false"
        );
        this.falseButton.type = "button";
        this.falseButton.textContent = this.falseButtonText;
        buttonGroup.appendChild(this.falseButton);
    
        this.trueButton = document.createElement("button");
        this.trueButton.classList.add(
          "confirm-dialog-button",
          "confirm-dialog-button--true"
        );
        this.trueButton.type = "button";
        this.trueButton.textContent = this.trueButtonText;
        buttonGroup.appendChild(this.trueButton);
      }
    
      _appendDialog() {
        this.parent.appendChild(this.dialog);
      }
    
      _destroy() {
        this.parent.removeChild(this.dialog);
        delete this;
      }
    
    さて、最後の部分.を作成しましょうconfirm() メソッド.その中で我々は、モーダルを表示し、2つのyes/noボタンのイベントリスナーを作成し、それらを解決するために必要がありますtrue or false そうすると、コンポーネント自体のあらゆる痕跡を取り除きます.
    confirm() {
      return new Promise((resolve, reject) => {
        const somethingWentWrongUponCreation = 
          !this.dialog || !this.trueButton || !this.falseButton;
        if (somethingWentWrongUponCreation) {
          reject("Something went wrong upon modal creation");
        }
    
        this.dialog.showModal();
    
        this.trueButton.addEventListener("click", () => {
          resolve(true);
          this._destroy();
        });
    
        this.falseButton.addEventListener("click", () => {
          resolve(false);
          this._destroy();
        });
      });
    }
    
    いいねここでテストしました.