location.hashを使ってモーダルウィンドウを出し分ける

今回はJavaScriptの location.hash を利用して異なるモーダルウィンドウの出し分けを実装したいと思います!

実用例としてはTwitterやFacebookなどでシェアする際に記事のURL末尾に#ハッシュをつけてシェアします。

リンクをクリックしたユーザーはTwitterなら#_tw、Facebookなら#_fbがURL末尾に付くのでそのハッシュ値を検知して異なる動作をすることができる仕組みになります。

例としてTwitterもしくはFacebookからのリンクでアクセスしてきたユーザーに「それぞれののクーポンを表示する」というモーダルウィンドウを実装してみましょう。

実装例

まずはモーダルウィンドウ非表示の状態です。
例として #_tw#_fb のURLをブラウザの検索欄に表示されていることを確認してください。
URL部分

検索欄に記述してあるURLに以下のようなハッシュをつけることで、モーダルウィンドウが表示されます。
ハッシュ値追加

ハッシュ値に #_tw ならTwitter用のモーダルウィンドウ、#_fb ならFacebook用のモーダルウィンドウが表示されます。
Twitter用モーダルウィンドウ
Facebook用モーダルウィンドウ

URL検索欄を使用する為このサイト内の埋め込みでは動作しません。
実際のデモはCodePenで直接ご確認ください!

HTML

<div class="contents">
  <h1>URL末尾にハッシュをつけてね!</h1>
  <h2>例:</h2>
  <p>#_tw<br>https://codepen.io/Higemura/pen/gjOOaY#_tw</p>
  <p> #_fb<br>https://codepen.io/Higemura/pen/gjOOaY#_fb</p>
</div>

<div data-hash="_tw" class="modal js-modal">
  <div class="modal_bg js-modal-close"></div>
  <div class="modal_content">
    <p class="modal_label">Twitterからのユーザー限定クーポンはこちら↓</p>
    <a class="modal_coupon" href="">Twitter限定 クーポン</a>
  </div>
</div>

<div data-hash="_fb" class="modal js-modal">
  <div class="modal_bg js-modal-close"></div>
  <div class="modal_content">
    <p class="modal_label">Facebookからのユーザー限定クーポンはこちら↓</p>
    <a class="modal_coupon" href="">Facebook限定 クーポン</a>
  </div>
</div>

CSS(SCSS)

body {
  background-color: #dfdfdf;
}
.contents {
  max-width: 600px;
  margin: auto;
  background-color: #ffffff;
  padding: 30px;
  h1 {
    text-align: center;
    margin-bottom: 40px;
  }
}

// ここからモーダル部分
.modal {
  &_bg {
    display: block;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.6);
    position: fixed;
    z-index: 1;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
  } 
  &_content {
    width: 500px;
    height: auto;
    background-color: #ffffff;
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    z-index: 2;
    padding: 60px;
  }
  &_label {
    font-size: 14px;
    font-weight: 600;
    text-align: center;
    margin: 0 0 20px;
  }
  &_coupon {
    display: block;
    text-decoration: none;
    background-color: #E85888;
    width: 240px;
    margin: auto;
    padding: 6px 12px;
    border-radius: 3px;
    text-align: center;
    color: #ffffff;
    font-size: 20px;
    font-weight: 600; 
  }
}

// モーダル表示切り替え
.js-modal {
  display: none;
  &.-active {
    display: block;
  }
}

JavaScript

// location.hash はURLのハッシュを取得します
const hash = location.hash;
// .js-modal を取得
const modals = document.getElementsByClassName('js-modal');

// modals をループさせる
for(let i = 0; i < modals.length; i++) {
  
  // getAttributeで modals の データ属性を取得(data-hash)
  const matchID = modals[i].getAttribute('data-hash');
  
  // location.hash で取得したハッシュ値と data-hash が一致したら
  if (hash === '#' + matchID) {
    // 一致した.js-modal にクラス名 -active を追加し表示させる
    modals[i].classList.add('-active');
    
    // モーダルウィンドウを閉じる動作
    const modalClose = document.getElementsByClassName('js-modal-close');
    // モーダルクローズクリックイベント
    modalClose[i].addEventListener('click', () => {
      // .-activeを削除
      modals[i].classList.remove('-active');
    });
  }
};

解説

HTML

最初に表示されている、モーダルウィンドウ以外の部分は contents というクラス名を指定
モーダルウィンドウのクラスは .modal とし、URLのハッシュ値によって クラス modalに設定してある data-hash が一致したら表示されます。

CSS(SCSS)

.modal 部分がモーダルウィンドウです。
&_label などSCSSを活用した記法になっています。

JavaScript

イベントを発火させるために .js-modal と .js-modal-close というjs-から始まるクラスを用意しました。
このようにCSSとJavaScript用のクラスを別に用意しておくことで、クラスを付け替えたり、変更した際に壊れる影響が少なくなります。

まずはハッシュを検知するための location.hash とモーダルウィンドウのイベントを取得するためのクラスjs-modalを定義しておきます。

const hash = location.hash;
const modals = document.getElementsByClassName('js-modal’);

modalsをループさせてgetAttributeで modals の データ属性を取得(data-hash)します。(console.logで確認すると _twと _fb が取得できると思います)

for(let i = 0; i < modals.length; i++) {
  const matchID = modals[i].getAttribute('data-hash’);
  etc...
}

location.hash で取得したハッシュ値と data-hash が一致したら一致した.js-modal にクラス名 -active を追加し表示させます。(CSSで-activeになるとdisplay: block; を付与します)

if (hash === '#' + matchID) {
  modals[i].classList.add('-active’);

以下はモーダルウィンドウを閉じる動作です。

今回の目的である「ハッシュ値を検知して異なるモーダルウィンドを出し分ける」部分には必要ありませんが、閉じる動作があればユーザーに優しいですね。
モーダルウィンドウが表示されている際の透過黒地オーバーレイ部分をクリックしたら動作する処理です。

const modalClose = document.getElementsByClassName('js-modal-close');
// モーダルクローズクリックイベント
modalClose[i].addEventListener('click', () => {
  // .-activeを削除
  modals[i].classList.remove('-active');
});

まとめ

location.hashを使ってモーダルウィンドウの出し分けを実装しました!
取得したハッシュ値をif文で条件分岐しているだけなので特に難しいことはありません。
#hash のようなハッシュはモーダルウィンドウ以外にページ内リンクなどにも良く使用されいるので色々な応用に使えますね。
動作デモはCodePenのサイト内でご確認ください!
Codepenデモ