カスタムスタッズトーストを作成する方法


この記事は最初に発表されたwebinuse.com
我々はいくつかのアプリを構築するたびに、我々はスタックトーストを必要とするチャンスがあります.トーストは、基本的に、彼らがコントロールすることができない若干の行動のユーザーに知らせる通知です.例えば、ネットワーク接続が失われ、データが保存され、エラーが発生します.時々、複数の通知を一度に表示する必要があります.
最初にやるべきことは、基本的なHTMLテンプレートを作ることです.
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>

</body>
</html>
vscodeとemmetを使用できます.我々がタイプするときhtml:5 空で.HTMLファイル、そして、我々はタブを押すと、エメットは上記と同じboilerplateを作成します.

JavaScriptの追加
今私たちのアプリにいくつかのJavaScriptを追加する必要があります.
function createToast(heading = "No heading", message = "No message") {
  //Create empty variable for toasts container
  let container;
  //If container doesn't already exist create one
  if (!document.querySelector("#toast-holder")) {
    container = document.createElement("div")
    container.setAttribute("id", "toast-holder");
    document.body.appendChild(container);
  } else {
    // If container exists asign it to a variable
    container = document.querySelector("#toast-holder");
  }

  //Create our toast HTML and pass the variables heading and message
  let toast = `<div class="single-toast fade-in">
                  <div class="toast-header">
                    <span class="toast-heading">${heading}</span>
                    <a href="#" class="close-toast">X</a>
                  </div>
                  <div class="toast-content">
                    ${message}
                  </div>
               </div>`;

  // Once our toast is created add it to the container
  // along with other toasts
  container.innerHTML += toast;

}


createToast();
createToast("This is heading", "This is the message");
コードスニペットを分析しましょう.関数を作成しましたcreateToast() . この関数は2つのパラメータを受け取ります:heading and message . これらの2つはトーストの見出しとトーストのコンテンツとしてトーストに渡されます.を返します.heading 値は'No heading'message 値は'No message' .
その後、我々は空を作成しましたcontainer 変数.この変数には、#toast-container . なぜ、我々はこれをしましたか?なぜ作成div HTMLで?我々は動的にスタックのトーストを作成しているので、我々はページを完全に制御する必要があります.我々は、我々のレイアウトでこのコンテナを混乱させたくありません.また、これはCSSコードとより少ないHTMLコードを意味します.それはあまりではなく、赤ちゃんのステップです.
それから、我々は我々のトーストのためにHTMLをつくりました、そして、我々は始めから我々の変数を渡しましたheading and message . このHTMLを作成したら、コンテナにトーストを追加します.我々が見ることができるように、我々は2回機能を呼びました.最初にパラメータを渡さず、2回目のパラメータを渡しました.これは我々が得たものです.

結果のスクリーンショット

我々の積み重ねた乾杯を美しくしましょう
私たちにはCSSがありませんので、すべてが私たちを待っているところにあります.それで、いくつかのCSSを加えましょう.
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: sans-serif;
}
#toast-holder {
  position: fixed;
  right: 20px;
  top: 20px;
  width: 200px;
  display: flex;
  flex-direction: column;
}

.single-toast {
  width: 200px;
  border-radius: 5px;
  background-color: white;
  color: #5b5b5b;
  margin-bottom: 20px;
  box-shadow: 0 5px 10px rgba(0,0,0,.5);
  transition: .3s;
  max-height: 100px;
  display: flex;
  flex-direction: column;
}

.toast-header {
  display: flex;
  justify-content: space-between;
  padding: 5px 10px;
  border-bottom: 1px solid #ccc;
}
.close-toast {
  color: inherit;
  text-decoration: none;
  font-weight: bold;
}
.toast-content {
  padding: 10px 10px 5px;
}

.fade-in {
  animation: fadeIn linear .5s;
}

.fade-out {
  animation: fadeOut linear .5s;
}

@keyframes fadeIn {
  0% {
    opacity: 0;
    max-height: 0px;
  }

  100% {
    opacity: 1;
    max-height: 100px;
  }
}

@keyframes fadeOut {
  0% {
    opacity: 1;
    max-height: 100px;
  }
  100% {
    opacity: 0;
    max-height: 0;
  }
}
我々がした最初のことは、何もマージンまたはパディングを持っていなかったことを確認したbox-sizingborder-box . コードのこの部分は、奇妙なオーバーフローを持っていないことを確認します.その後、我々は設定position:fixed 我々のコンテナでは、ページレイアウトを混乱させません.また、画面の右側にあることを確認しました.これとは別にdisplay: flex; flex-direction: column; , なぜなら、私たちはお互いの上に積み重ねて乾杯する必要があるからです.
それから、我々は我々の積み重ねた乾杯のために若干のスタイルを加えました.おそらく、説明する必要がある唯一のものはmax-height . CSSではアニメーションできませんheight , しかし、我々はmax-height . それがこのプロパティを使用した理由です.また、我々は2つのアニメーションを作成しましたfadeIn and fadeOut . それで、我々は入口と出口を後で動けます.これが今得たものです.

結果のスクリーンショット
ご覧の通りレイアウトも変わり、トーストのスタイリングも変わりました.今、我々は我々のスタック可能なトーストを削除するための関数を作成する必要があります.我々は、永遠にそこに彼らを望みません.
function removeToast(e) {
  //First we need to prevent default
  // to evade any unexpected behaviour
  e.preventDefault();

  //After that we add a class to our toast (.single-toast)
  e.target.parentNode.parentNode.classList.add("fade-out");

  //After CSS animation is finished, remove the element
  setTimeout(function() {
    e.target.parentNode.parentNode.parentNode.removeChild(e.target.parentNode.parentNode)
  }, 500);
}
我々はremoveToast() 関数とイベントパラメータを渡します.我々がクリックしている時からa タグ、我々は任意の不要な動作を防ぐためにしたいe.preventDefault() . その後、新しいクラスを割り当てました.fade-out 我々に.single-toast それで、我々は良い出口アニメーションを持っています.アニメーションが終了したら、私たちは完全にDOMからトーストを削除します.
今、我々はこの関数をcreateToast 関数と作成eventListener . 改訂版を見ましょうcreateToast() 関数.
function createToast(heading = "No heading", message = "No message") {
  //Create empty variable for toasts container
  let container;
  //If container doesn't already exist create one
  if (!document.querySelector("#toast-holder")) {
    container = document.createElement("div")
    container.setAttribute("id", "toast-holder");
    document.body.appendChild(container);
  } else {
    // If container exists asign it to a variable
    container = document.querySelector("#toast-holder");
  }

  //Create our toast HTML and pass the variables heading and message
  let toast = `<div class="single-toast fade-in">
                  <div class="toast-header">
                    <span class="toast-heading">${heading}</span>
                    <a href="#" class="close-toast">X</a>
                  </div>
                  <div class="toast-content">
                    ${message}
                  </div>
               </div>`;

  // Once our toast is created add it to the container
  // along with other toasts
  container.innerHTML += toast;


  /**
   * THIS PART WE HAVE ADDED
   * */

    //Save all those close buttons in one variable
    let toastsClose = container.querySelectorAll(".close-toast");

  //Loop thorugh that variable
  for(let i = 0; i < toastsClose.length; i++) {
      //Add event listener
    toastsClose[i].addEventListener("click", removeToast,false);
  }

}


function removeToast(e) {
  //First we need to prevent default
  // to evade any unexpected behaviour
  e.preventDefault();

  //After that we add a class to our toast (.single-toast)
  e.target.parentNode.parentNode.classList.add("fade-out");

  //After CSS animation is finished, remove the element
  setTimeout(function() {
    e.target.parentNode.parentNode.parentNode.removeChild(e.target.parentNode.parentNode)
  }, 500);
}


createToast();
createToast("This is heading", "This is the message");
残っている唯一のものは、空であれば容器を取り除くことです.
function isEmpty(selector) {
    return document.querySelector(selector).innerHTML.trim().length == 0;
}
私たちがここでしたことはinnerHTML が空です.しかし、その前に、空のスペースをトリミングすることを確認しました.このようにして、空のスペースをJavaScriptでテキストとして「カウント」することを防いだ.この関数は、removeToast() 関数.なぜ?スタック可能なトーストが削除された後にチェックされることを確認したいので.改善しましょうremoveToast() 関数.
function removeToast(e) {
  //First we need to prevent default
  // to evade any unexpected behaviour
  e.preventDefault();

  //After that we add a class to our toast (.single-toast)
  e.target.parentNode.parentNode.classList.add("fade-out");

  //After CSS animation is finished, remove the element
  setTimeout(function() {
    e.target.parentNode.parentNode.parentNode.removeChild(e.target.parentNode.parentNode);

    /**
     * WE HAVE ADDED THIS PART
     * */

    if (isEmpty("#toast-holder")) {
        console.log(isEmpty("#toast-holder"));
        document.querySelector("#toast-holder").parentNode.removeChild(document.querySelector("#toast-holder"));
    }
  }, 500);
}
function isEmpty(selector) {
    return document.querySelector(selector).innerHTML.trim().length == 0;
}
我々は、Codepenの上で我々の積み重ねられたトーストのライブの例をチェックアウトすることができます.
何か質問があれば何か私のものに私を見つけることができますかHow to easily add a WordPress menu to a custom theme .