【JavaScript】ボタン押してダイアログ表示する方法~外タップで閉じる方法も~

中山テック 代表の中山です。

とある人気ゲームレビュー東京競馬場中山競馬場のブログをちょっと前に分割しました。

その際に見たい内容が分散してしまい「どこのブログに載っていたか」がわかり辛い!

ということもあり、各テーマでの索引を追従メニューとして追加しました。

どのように実装すれば良いのか、JavaScript&CSSのプログラムを交えてご紹介いたします。





※東京競馬場ブログの一部を抜粋

7分割されたブログ全てに実装、画面左下を追従していく作りとなっております。

ボタンをタップ(PC版はクリック)するとこのようなダイアログが出ます。

青い文字はリンクとなっており、タップすると該当のページに飛べます。

開発する際の意識

中山競馬場Verも開発済み

まず見た目については「どのようなUIにするか」という点。

さらに「どうプログラムを組むか」を考察し「CSSは必要か」「JavaScriptは必要か」といった具体的ポイントも考察。

それでもイメージが沸かない場合はテキストでもExcelでもいいので設計書を作るのが吉です。

観点作業内容
UI1.画面最下にメニューを配置(ボタン)
2.ボタンを押すとダイアログ全面に
3.ダイアログに見出しとリンク配置
4.ダイアログ外をタップすると閉じる
組み立て1.CSSで最下にボタン固定配置
2.各テーマのIDがあるかどうか判定
3.ボタンのIDがあるかどうか判定
4.ボタンタップ後のイベントリスナー設定(JS)
5.ダイアログ閉じる際のイベントリスナー設定(JS)

実装

HTML

<div id="sakuin-select"> ⇒①
  <button id="sakuinButton" class="koukoku-select">中山索引</button>
</div>

<dialog id="sakuinDialog"> ⇒②
  <div id="nakayamaDialogInner"></div>
</dialog>

※中山競馬場ブログの索引追従を例に取ってます

①はボタン配置エリアとなります。

以前のブログでもHTMLはDIVタグでエリアを決め、CSSで位置やサイズを制御しております。

②はダイアログ領域なのですが、JavaScript「showModal」を指定して起動します。

今回はボタンクリック後起動ですが、ページ開いたときにダイアログを表示させたい場合はdialogタグにopenを指定します。

DIVタグのID「nakayamaDialogInner」は東京競馬場とゲームブログで名前が変わります。

「中山索引」「nakayamaDialogInner」と付随するリストだけ変更すればリスト流用できる仕組みにしてます。

CSS

#sakuin-select {
  position: fixed;
  display: block;
  z-index: 998;
  bottom: 30px;
}

今回はダイアログ中心なのでボタンの動きは割愛。

ボタンの位置を指定するCSSをご紹介いたします。

ポジションは画面最下から30px分上に配置。

z-indexを指定することで最前面に表示される制御を施します。



  • システム開発関連記事

JavaScript

このUIはJavaScript中心と言っても過言ではありません。

基本「onload(ページ開いてHTMLが全て表示された後に行われる処理)」内に記述しております。

ダイアログにメニューを設定

// メニュー固定&ダイアログ対応 ※中山競馬場
if(document.getElementById('nakayamaDialogInner') != null) {
  document.getElementById('nakayamaDialogInner').innerHTML = nakayamaDialogInnerList;
}

~中略~
const nakayamaDialogInnerList = ' \
  【大分類】<br>\
  <a href="https://nakayama-tech.com/2021/12/12/nakayama-keiba/">TOP</a><br>\
  <a href="https://nakayama-tech.com/2023/11/06/nakayama-keiba-access-uchibaba/">アクセス・入場方法</a><br>\
  <a href="https://nakayama-tech.com/2023/11/06/nakayama-keiba-shisetsu/">各種施設のご案内</a><br>\
・
・
・
【他】<br>\
<a href="https://nakayama-tech.com/2023/11/06/nakayama-keiba-parkwins/#i-5">TUFFY SHOP</a><br>\
';

前提として索引ボタンを配置していないページの方が多いです。

「nakayamaDialogInner」のIDは中山競馬場ブログ以外存在しないので、このIF分がないとJSエラーが発生します。

ここは「nakayamaDialogInnerList」内のリストをダイアログに設定するだけの処理です。

ダイアログ表示制御

↓↓↓ グローバル領域
 ↓↓↓

var buttonId;        // メニューボタン
var sakuinDialog;    // ダイアログメニュー

↓↓↓ onload領域 ↓↓↓

// メニュー固定&ダイアログ対応 ボタン設定
if(document.getElementById("sakuinButton") != null) {
  buttonId = document.getElementById("sakuinButton"); ⇒①
}
// メニュー固定&ダイアログ対応 ダイアログ設定
if(document.getElementById("sakuinDialog") != null) {
  sakuinDialog = document.getElementById("sakuinDialog"); ⇒②
}

//ダイアログを開くイベント
if(buttonId != null) {
  buttonId.addEventListener("click", () => {
    sakuinDialog.showModal(); ⇒③
  });
}

//ダイアログを閉じるイベント
if(sakuinDialog != null) {
  sakuinDialog.addEventListener('click', (event) => {

    if(document.getElementById('karizDialogInner') != null) {
      if(event.target.closest('#karizDialogInner') === null) {
        sakuinDialog.close();
      }
    } else if(document.getElementById('fuchuDialogInner') != null) {
      if(event.target.closest('#fuchuDialogInner') === null) {
        sakuinDialog.close();
      }
    } else if(document.getElementById('nakayamaDialogInner') != null) {
      if(event.target.closest('#nakayamaDialogInner') === null) {
        sakuinDialog.close(); ⇒④
      }
    }
  });
}

①はボタンのオブジェクトを、②はダイアログのオブジェクトを取得します。

メニューを置いてるブログ以外は存在しないIDのため制御を入れてます。

③はボタンIDが存在する場合にボタンをクリックするとダイアログを開く、という命令文です。

※HTMLで表記した「sakuinDialog」が「Dialog」タグでないとエラーが出ます。

④ではゴチャついた処理ですが、「nakayamaDialogInner」のダイアログ領域外をタップした時に閉じる処理を入れてます。

ダイアログはclose処理を入れないと永遠に残るので忘れないようにしましょう!



まとめ

JavaScriptを駆使してボタンタップ⇒ダイアログ表示⇒閉じる方法についてご説明しました。

ソースコードが全量見せられないのは残念ですが、処理の仕組みをご理解頂ければと!

もし実装したいけど難しいという場合、ご依頼を承りますので遠慮なくお申しつけください!

※ご料金が発生します

無限の可能性を秘めているJavaScript、是非皆様も試してみて下さい!

最後までご覧頂き、ありがとうございました。

※中山テックに掲載しているゲーム画像の著作権、商標権、その他知的財産権は、当該コンテンツの提供元に帰属します


おすすめの記事