jQuery+ajaxでモーダルのコンテンツを取得する方法

jQuery+ajaxでモーダルのコンテンツを取得する方法

Posted at March 17,2024 12:03 AM
Tag:[Ajax, jQuery]

jQuery+ajaxでモーダルのコンテンツを取得する方法を紹介します。

1.はじめに

モーダル表示の使い方は、たとえば商品ページで、その商品の詳細画像を表示するといったことが多いと思います。

その場合、HTMLページ内にすべてのモーダル用コンテンツを配置して、そこから取得・表示する実装になると思います。

ですが、ページ内にモーダル用のコンテンツをすべて記述すると、場合によってはページのサイズが大きくなり、ロード時間に影響します。

また商品ページではなく、たとえばモーダルをブログの記事ページとして表示させたい場合、上記の方法では大量のコンテンツをページ内に書き出す必要がありますが、現実的ではありません。

ということで、本記事ではモーダル用コンテンツをjQuery+ajaxで取得し、さらの前後リンクのコンテンツもjQuery+ajaxで取得する方法を紹介します。

2.サンプル

下記のリンクをクリックするとサンプルページに遷移します。

モーダルサンプル

テキスト途中にある「ひらく」をクリックするとモーダルが表示され、前後リンクをクリックするとコンテンツをajaxで読み出して表示を切り替えます。

「あああ」のテキストを大量に挿入しているのは、モーダル表示後にスクロールしてもモーダルが移動しないことを示すためのものです。

サンプルはモーダルコンテンツの取得と前後リンクだけに着目しているので、CSSは最小限です。またアニメーションや「閉じる」ボタンの実装もありません。

以下、ソースとjQueryの解説です。

3.ソース

<meta charset="UTF-8" />
<style>
#modal {
    display: block;
    position: fixed;
    opacity: 1;
    z-index: 11000;
    left: 45%;
    margin-left: -77px;
    top: 100px;
}
#modal_content {
    border: 1px solid #000000;
    padding: 30px;
}
#left {
  position: absolute;
  top: 100px;
  left: -170px;
}
#right {
  position: absolute;
  top: 100px;
  right: -170px;
}
</style>
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
<script>
$(function(){
    $(".open_modal").on('click', function(){
        var url = $(this).attr('data-url');
        $.ajax({
            type: "POST",
            url: url,
            dataType: "html"
        }).done(function(data) {
            let main = $($.parseHTML(data)).filter('#main').html();
            let prev = $($.parseHTML(data)).filter('#previous').text();
            let next = $($.parseHTML(data)).filter('#next').text();
 
            $('#modal_content').html(main);
 
            if ( prev ) {
               $('#left').attr('data-url', prev);
               $('#left').css('display', 'block');
            } else {
               $('#left').css('display', 'none');
            }
            if ( next ) {
               $('#right').attr('data-url', next);
               $('#right').css('display', 'block');
            } else {
               $('#right').css('display', 'none');
            }
 
            $('#modal').css('display', 'block');
        });
    });
});
</script>
 
r />あああ</p>
<p>あああ<br />あああ<br />あああ<br />あああ<br />あああ<br />あああ<br />あああ<br />あああ<br />あああ<b
r />あああ</p>
<p>あああ<br />あああ<br />あああ<br />あああ<br />あああ<br />あああ<br />あああ<br />あああ<br />あああ<b
r />あああ</p>
<p>あああ<br />あああ<br />あああ<br />あああ<br />あああ<br />あああ<br />あああ<br />あああ<br />あああ<b
r />あああ</p>
 
<div class="open_modal" data-url="https://www.koikikukan.com/samples/20240313/test1.html">ひらく</div>
 
r />あああ</p>
<p>あああ<br />あああ<br />あああ<br />あああ<br />あああ<br />あああ<br />あああ<br />あああ<br />あああ<b
r />あああ</p>
<p>あああ<br />あああ<br />あああ<br />あああ<br />あああ<br />あああ<br />あああ<br />あああ<br />あああ<b
r />あああ</p>
<p>あああ<br />あああ<br />あああ<br />あああ<br />あああ<br />あああ<br />あああ<br />あああ<br />あああ<b
r />あああ</p>
 
  <div id="modal" style="display:none;">
    <div class="open_modal" id="left" data-url=""><</div>
    <div class="open_modal" id="right" data-url="">></div>
    <div id="modal_content"></div>
  </div>

4.解説

「ひらく」のclass属性"open_modal"をclickイベントで待ち合わせます。

<div class="open_modal" data-url="https://www.koikikukan.com/samples/20240313/test1.html">ひらく</div>
 :
<script>
$(function(){
    $(".open_modal").on('click', function(){

クリックされると要素内のdata-url属性値に設定したURLをattrメソッドで取得します。

        var url = $(this).attr('data-url');

data-urlの値は下記のdata()でも取得できますが、この方法ではDOMのキャッシュが誤って取得されてしまうため、この記事の執筆時点ではdata()は絶対に使わないでください(この事象で2日ほど悩みました)。

        var url = $(this).data('url');

取得したURLでコンテンツをajaxで取得します。

        $.ajax({
            type: "POST",
            url: url,
            dataType: "html"

$.ajax以外に$getでも取得可能です。

なお非同期による取得ではキャッシュが取得されてしまうこともあるので、POSTメソッドを使用する、cacheオプションをfalseにする等の対処を行ってください。

取得したコンテンツをそのままHTMLに展開できないケースを考慮して、部分取得を行います。

ここではコンテンツ部分と前後リンク部分をparseHTML()とfilter()を使います。この方法がベストプラクティスと思われます。

        }).done(function(data) {
            let main = $($.parseHTML(data)).filter('#main').html();
            let prev = $($.parseHTML(data)).filter('#previous').text();
            let next = $($.parseHTML(data)).filter('#next').text();

取得したHTMLをモーダルに反映します。

            $('#modal_content').html(main);

URLを前後リンクに反映させます。このときも前述と同様の理由でdata()ではなく、attr()を使用してください。リンクがない場合は非表示にしています。

            if ( prev ) {
               $('#left').attr('data-url', prev);
               $('#left').css('display', 'block');
            } else {
               $('#left').css('display', 'none');
            }
            if ( next ) {
               $('#right').attr('data-url', next);
               $('#right').css('display', 'block');
            } else {
               $('#right').css('display', 'none');
            }

すべての設定が終わったらdisplayプロパティを使ってモーダル全体を表示します。

           $('#modal').css('display', 'block');
関連記事
トラックバックURL


コメントする
greeting

*必須

*必須(非表示)


ご質問のコメントの回答については、内容あるいは多忙の場合、1週間以上かかる場合があります。また、すべてのご質問にはお答えできない可能性があります。予めご了承ください。

太字イタリックアンダーラインハイパーリンク引用
[サインインしない場合はここにCAPTCHAを表示します]

コメント投稿後にScript Errorや500エラーが表示された場合は、すぐに再送信せず、ブラウザの「戻る」ボタンで一旦エントリーのページに戻り(プレビュー画面で投稿した場合は、投稿内容をマウスコピーしてからエントリーのページに戻り)、ブラウザをリロードして投稿コメントが反映されていることを確認してください。

コメント欄に(X)HTMLタグやMTタグを記述される場合、「<」は「&lt;」、「>」は「&gt;」と入力してください。例えば「<$MTBlogURL$>」は「&lt;$MTBlogURL$&gt;」となります(全て半角文字)