jQueryを使わずES2015でスライダー対応のポップアップテンプレートをつくってみた。

今回はスライダー対応のポップアップテンプレートを作成してみました。簡単なポップアップのテンプレートが欲しい場合はこちらを参考にしてみてください!

top-men.hatenablog.com

スライダー対応のポップアップのイメージはこちら になります。

ライブラリに依存するることは学習コストが掛かるので極力使いたくはありません。ですがプロジェクトによってはスケジュールやメンバーなどを考慮して使用することが正しいときもあるでしょう。

ですが、今回はjQueryなどを使わずに流用できるものを紹介します。

早速ですがコードを見てみましょう。

<!DOCTYPE html>
<html lang='en'>
<head>
   <meta charset='UTF-8'>
   <meta name='viewport' content='width=device-width, initial-scale=1.0'>
   <meta http-equiv='X-UA-Compatible' content='ie=edge'>
   <title>Document</title>
   <link rel='stylesheet' href='css/style.css'>
   <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.26.0/babel.min.js"></script>
   <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/6.26.0/polyfill.min.js"></script>
</head>
<body>
  <h1>ポップアップデモ</h1>
    <p>画像をクリック</p>
    <p><img src='images/img_01.jpg' alt='' class="popup_image"></p>
    <p>大海原だぁぁ</p>
    <p><img src='images/img_02.jpg' class="popup_image" alt=''></p>
    <p>海もいいけど山菜食べたい</p>
    <p>山登ろう</p>
    <p>頂上の風景綺麗だな</p>
    <p><img src='images/img_03.jpg' alt='' class="popup_image"></p>
    <p>気づけばもう冬かぁ</p>
    <p><img src='images/img_04.jpg' alt='' class="popup_image"></p>
    <!---ポップアップ-->
    <div class="popupSlider" id="popupWrap">
        <div class="popupSlider_content">
            <div class='closeBtn' id="js-closeBtn">X</div>
            <p class="poupSldier_content_arrow prev" id="sliderPrevArrow"></p>
            <p class="popupSlider_content_img"><img src='' alt='' class="" id="poupSliderImg"></p>
            <p class="poupSldier_content_arrow next" id="sliderNextArrow"></p>
        </div>
    </div>
    <!-- <script src="js/Popup.js"></script> -->
    <script src="js/PopupSlider.js"></script>
</body>
</html>
img {
    max-width: 100%;
}

.popupButton {
    border: none;
    background: #323232;
    color: #fff;
    padding: 20px;
    border-radius: 33px;
    cursor: pointer;
}
.popup {
    width: 100%;
    height: 100%;
    position: fixed;
    top: 0;
    left: 0;
    background: rgba(5,5,5,0.8);
    opacity: 0;
    transition:all .3s;
    transform: scale(0);
}

.popup.is-active {
    transform: scale(1);
    opacity: 1;
}

.popup_content {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    background: #fff;
    width: 400px;
    height: 360px;
    padding: 30px;
}

.popup_content_closeButton {
    cursor: pointer;
    text-align: right;
}

.popup_content_description {
    margin-top: 30px;
}

.popup_image {
    width: 400px;
    cursor: pointer;
}

/* ポップアップのスライダー用のクラス*/

.popupSlider {
    width: 100vw;
    height: 100vh;
    position: fixed;
    opacity: 0;
    top: 0;
    left: 0;
    background:rgba(0, 0, 0, .6);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: -1;
    transition: all .3s;
}

.popupSlider.is-active {
    opacity: 1;
    z-index: 1000;
}

.popupSlider_content {
    display: flex;
    width: 600px;
    justify-content: center;
    align-items: center;
    position: relative;
    padding: 30px;
    background: #fff;
}

.popupSlider_content_img {
    width:100%;
    padding: 0 20px;
}

.poupSldier_content_arrow:before {
    content: "◀";
    position: absolute;
    display: block;
    color: #fff;
    display: flex;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%,-50%);
}

.poupSldier_content_arrow {
    width: 80px;
    height: 60px;
    background: #000;
    cursor: pointer;
    margin: 0;
    border-radius: 50%;
    padding: 0;
    position: relative;
}

.poupSldier_content_arrow.next {
    transform: rotate(180deg);
}

.closeBtn {
    position: absolute;
    top: 10px;
    right: 40px;
    position: absolute;
    top: 10px;
    right: 15px;
    border-radius: 50%;
    border: 1px solid #323232;
    padding: 10px;
    width: 20px;
    height: 20px;
    background: #323232;
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
}
class PopupSlider {
  constructor(imageElements) {
    this.el = document.getElementById("popupWrap");
    this.imgEl = document.getElementById("poupSliderImg");
    this.closeBtn = document.getElementById("js-closeBtn");
    this.allImgElms = imageElements;
    this.setEventListeners();
  }

  togglePopupState(flag) {
    if (flag) {
      this.el.classList.add("is-active")
    } else {
      this.el.classList.remove("is-active")
    }
  }

  changeImage(src) {
    this.imgEl.setAttribute("src", src);
  }

  slideNext(src) {
    this.changeImage(src);
  }

  slideBack(src) {
    this.changeImage(src);
  }

  setEventListeners() {
        for(let i = 0; i < this.allImgElms.length; i++) {
      this.allImgElms[i].addEventListener("click", e => {
        const clickImgSrc = e.target.getAttribute("src");
        this.imgEl.setAttribute("src", clickImgSrc)
        this.togglePopupState(true);
      });
    }
    this.closeBtn.addEventListener("click", e => {
      this.togglePopupState(false);
    })

    document.getElementById("sliderNextArrow").addEventListener("click", e => {
      const currentSrc = document.getElementById("poupSliderImg").getAttribute("src");
      for(let i = 0; i < this.allImgElms.length; i++) {
        const src = this.allImgElms[i].getAttribute("src");
        if (src === currentSrc) {
          if (this.allImgElms.length <= i+1) {
            this.slideNext(this.allImgElms[0].getAttribute("src"));
            return
          };
          this.slideNext(this.allImgElms[i+1].getAttribute("src"));
        }
      }
    });

    document.getElementById("sliderPrevArrow").addEventListener("click", e => {
      const currentSrc = document.getElementById("poupSliderImg").getAttribute("src");
      for(let i = 0; i < this.allImgElms.length; i++) {
        const src = this.allImgElms[i].getAttribute("src");
        if (src === currentSrc) {
          if (Array.from(this.allImgElms).indexOf(this.allImgElms[i]) <= 0) {
            this.slideBack(this.allImgElms[this.allImgElms.length -1].getAttribute("src"));
            return;
          };
          this.slideBack(this.allImgElms[i-1].getAttribute("src"));
        }
      }
    });
  }
}

const imageElements = document.getElementsByClassName("popup_image");
const slider = new PopupSlider(imageElements);

const toArray = (htmlCollection) => {
  Array.prototype.slice.call(htmlCollection);
}

ここでテンプレートとして使用するために気をつける箇所いくつかあります。

  • ポップアップ&スライドショーで表示させたいimgタグにpopup_imageクラスを付与することです。
const imageElements = document.getElementsByClassName("popup_image");

上記のコードのクラス名をご自身の好きなクラス名にしていただいても構いません!

またArray.fromとコードの中で出てきていますが、こちらは配列型のオブジェクトから新しい配列インスタンスを生成しています。 ここでは配列にしたデータの方が扱い易くなるからです。

ポップアップによってスタイルを変更したい場合は、cssなどで調整してみてください。

簡単ではありますが以上になります。