質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.93%

javascriptでモーダルダイアログを表示する Magnific Popup が動かない

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 3,245

shaketonori

score 17

前提・実現したいこと

これまで自作(といってもどこかのサイトにあった jQuery版)のモーダルウィンドウを使っていましたが、レスポンシブ対応ということである Magnific Popup というプラグインに置き換えようとしています。

動作としては、最初に条件を与えてサムネール画像を一覧表示させ、一覧からひとつの画像クリックするとモーダルダイアログ画面が開いて画像を原寸で表示させる、というものです。

発生している問題・エラーメッセージ

ところが、サムネイルのどれをクリックしてもモーダルダイアログが開きません。
とくにエラーが出ることはなく、反応がない状態です。

該当のソースコード

【javascript モーダルダイアログの定義】
モーダルウィンドウに表示する内容は画像の他文字情報やデータ入力も行なうため、インライン情報なので以下の設定をしています。

$(function () {
    $('.popup-modal').magnificPopup({
        type: 'inline',
        preloader: false
    });
    //閉じるリンクの設定
    $(document).on('click', '.popup-modal-dismiss', function (e) {
        e.preventDefault();
        $.magnificPopup.close();
    });
});

下記のAjaxで2つの条件で検索に行き、画像を一覧表示させます。
【javascript Ajaxによる検索】

    $.ajax({
        type: "POST",
        url: "/PhotoSearchList",
        data: {"userId":userId, "blockTitle":blockTitle}, 
        dataType: 'text', 

        success: function(request){
            var json = JSON.parse(request);
            var res = '';
            res = '<ul class="photoList">';
            for (var i = 0; i < json.length; i++){
                res += '<li class="photoList"><a class="popup-modal" href="#inline-wrap"><img src="/PhotoSearchOneBlob?photoId=' + json[i].photoId + '"></a></li>'; ※※
            }
            res += '</ul>';
             var obj = document.getElementById("imgSrcList");
            obj.innerHTML = res ;
        },
        error: function(msg){
            alert( "Data Saved: " + msg );
        }
    });

【html部分】

<body>
    <div id="container">
    <!-- ▼▼▼▼▼▼ここからダイアログフォーム -->
    <div id="inline-wrap" class="mfp-hide">

         <div id="imgSrcOne">
                      <!-- ここに検索結果(1件)を表示 -->
        </div>

        <br />
        <table>
              <tr>
                  <td>対象図ID</td><td id="dPhotoId"></td><td>登録日</td><td id="dPhotoDate"></td>
                </tr>
               <tr>
                   <td>ブロックタイトル</td><td id="dBlockTitle"></td><td>対象図のタイトル</td><td id="dPhotoTitle"></td>
               </tr>
           </table>
        <input type="button" value="戻る" onClick="dispPrevious()" />
        <input type="button" value="進む" onClick="dispNext()" />

    </div>
    <!-- ▲▲▲▲▲▲ここまでダイアログフォーム -->

    <!-- ▼▼▼▼▼▼ここからメインフォーム -->
    <div id="content">
        <FORM id="fm">
            ブロックタイトル:<input type="text" id="blockTitle" name="blockTitle" /><br />
            <input type="button" value="クリア" onclick="clear();" />
            <input type="button" value="検索" onclick="search();" />
        </FORM>

        <div id="imgSrcList">
            <!-- ここに検索結果(一覧)を表示 -->
        </div>
    </div><!--contentの終了  -->

    以下省略

試したこと

問題を単純化するために※※の所を

res += '<li class="photoList"><a class="popup-modal" href="#inline-wrap">ダイアログ表示</a><br /></li>';

としてみて、表示された文字列「ダイアログ表示」をクリックしてみてもモーダルダイアログを開くことができませんでした。

また、単純に
<a class="popup-modal" href="#inline-wrap">ダイアログ表示</a>
をメインフォームに記述してクリックするとモーダルダイアログを開くことができました。

いろいろ調べてみたのですが、innerHTML でhtmlとして書き換える文字列の中に "<script>" などがあると期待している動作ができないようです。
ですが、今回はそれに該当しませんし、動的に内容が異なるので、innerHTML で html として書き換える方法しか思い浮かびません。

補足情報(言語/FW/ツール等のバージョンなど)

Ajaxの先のバックヤードは java で動いています。
ブラウザは通常 Firefox を使用していますが、この件に関しては Chrome , Edge も試してみましたが変わりませんでした。

よろしくお願い致します。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • kei344

    2017/05/23 11:23

    質問文のコードはそれぞれ個別にコードブロックで囲んでいただけませんか? ```(バッククオート3つ)で囲み、前後に改行をいれるか、コードを選択して「<code>」ボタンを押すとコードブロックになります。

    キャンセル

回答 1

checkベストアンサー

+2

$('.popup-modal').magnificPopup({}); を実行したタイミングで対象の要素がDOMに無いから動かないのだと思います。

innerHTML より後に実行してください。(さらに追加するような場合、magnificPopupにリフレッシュ的なメソッドがあればそれを実行し、無ければ追加分にのみ実行するような書き方にする必要があります)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/05/23 15:20

    kei344さん、回答ありがとうございます。

    innerHTML を調べているとき、「<script」タグでうまく動かないことや、DOMが作られない等の問題で
    ネット上で2・3記事が見つかったので、その辺が関係あるのかな、とは思っていました。

    ご指摘頂いた
    「実行したタイミングで対象の要素がDOMに無いから動かないのだと思います。innerHTML より後に実行してください。」
    は理屈では分かるのですが、res の内容をオブジェクトである("imgSrcList")のHTMLを書き替えるのですから

    var obj = document.getElementById("imgSrcList");
    obj.innerHTML = res ;

    とやるしかないように思います。

    innerHTML で先に記述してそのあとで実行させる方法が具体的にイメージできないで困っています。

    具体的な対応方法をもう少し詳しく教えて頂けないでしょうか。
    よろしくお願い致します。

    キャンセル

  • 2017/05/23 15:45

    「$('.popup-modal').magnificPopup({});」を最初に書かずに「obj.innerHTML = res ;」の次の行に書いてみればよいです。

    キャンセル

  • 2017/05/24 13:05

    kei344 さん、回答ありがとうございました。

    教えて頂いた通り、「obj.innerHTML = res ;」のあとに Magnific Popup の定義を記述したら、
    ダイアログが開くようになりました。

    当たり前といえば当たり前の修正ですが、指摘されて初めて気がつきました。ヤレヤレ

    本当にありがとうございました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.93%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る