ホーム DoRuby クリックをトリガーに$.ajaxで外部htmlを読み込んだり削除したりする
クリックをトリガーに$.ajaxで外部htmlを読み込んだり削除したりする
 

クリックをトリガーに$.ajaxで外部htmlを読み込んだり削除したりする

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

やりたいこと
「条件A」なら、A.html、「条件B」なら、B.html
のように、クリックした要素に応じた外部htmlを読み込み、
閉じるをクリックしたら外部html部分は削除したい。
読み込んだり削除したりを繰り返したい。
呼び出し元・外部htmlどちらでもjsが必要だけど、
jsファイルがすでにたくさんあるので1つにまとめたい。

$.ajaxで外部htmlを読み込む

まず、htmlでトリガーになる部分を作ります。

<a href="modal_A.html" class="js-modal_trigger">Aを選択</a>
<a href="modal_B.html" class="js-modal_trigger">Bを選択</a>

今回は読み込んだ後も別の外部htmlを読み込み直したりしたいので、
$.ajaxを使うことにします。

$(".js-modal_trigger").click(function(e) {
  e.preventDefault();
  //読み込みたい外部htmlのファイル名を取得
  var href = $(this).attr("href"); 

  //読み込んだファイルを展開するdivを作る
  $(this).after("<div class=\"js-modal\"></div>"); 

  $.ajax({
    type: 'GET',
    url: href,
    dataType: 'html',
    success: function(data) {
      //取得したhtmlを作成したdivに追加
      $(".js-modal").append(data);
    },
    error: function() {
      alert('問題がありました。');
    }
  });
});

読み込みたいhtmlが1種類ではないので、urlに入れる値はaタグのhrefから取得しています。
あと、読み込んだhtmlの展開用の空divが最初からhtml上にあるのも気持ち悪いので、
クリックのタイミングで毎回作ることにしました。

.remove()で要素を削除する

読み込みができたので、今度は閉じるをクリックしたら外部html部分を削除する部分を作ります。

<div class="js-modal_close">閉じる</div>

htmlを用意して、読み込まれた部分を削除するjsを追加。

$(".js-modal_close").click(function() {
  $(".js-modal").remove();
});

.js-modal_closeが読み込んだ外部htmlの中にある場合、
呼び出し元のページで上記のjsを読み込んでいても、このままでは動きません。
なので、これをfunctionにします。

function modalClose() {
  $(".js-modal_close").click(function() {
    $(".js-modal").remove();
  });
});

このfunctionを外部htmlを読み込んだ後に実行します。

$(".js-modal_trigger").click(function(e) {
  e.preventDefault();
  //読み込みたい外部htmlのファイル名を取得
  var href = $(this).attr("href"); 

  //読み込んだファイルを展開するdivを作る
  $(this).after("<div class=\"js-modal\"></div>"); 

  $.ajax({
    type: 'GET',
    url: href,
    dataType: 'html',
    success: function(data) {
      //取得したhtmlを作成したdivに追加
      $(".js-modal").append(data);
      modalClose(); //閉じる
    },
    error: function() {
      alert('問題がありました。');
    }
  });
});

閉じる以外にも、外部htmlでjsを実行したい場合は、
同じように関数にして読み込むと良さそうです。

番外:どんどん増殖する外部html

最初、何も考えずに外部htmlの中でjsファイルを読みこませて動かしてみたところ、
1回目のクリック…読み込み、削除問題なし。
2回目のクリック…外部htmlの要素が2回読み込まれる。
3回目のクリック…外部htmlの要素が4回読み込まれる。

明らかにおかしい。
クリックのイベントがいけないのかと思い、
試しにページロード時に外部htmlを読むようにしてみようと
ちょっと書き換えました。

$(".js-modal_trigger").each(function(e) {
  e.preventDefault();
  //読み込みたい外部htmlのファイル名を取得
  var href = $(this).attr("href"); 

  //読み込んだファイルを展開するdivを作る
  $(this).after("<div class=\"js-modal\"></div>"); 

  $.ajax({
    type: 'GET',
    url: href,
    dataType: 'html',
    success: function(data) {
      //取得したhtmlを作成したdivに追加
      $(".js-modal").append(data);
    },
    error: function() {
      alert('問題がありました。');
    }
  });
});

その結果、<div class=”js-modal”></div>を生成し、外部htmlを取り込む処理を
ひたすらループし続ける悲劇が…
止まらないのでブラウザを強制終了。
ちなみに、.load()でも同じように無限ループが発生しました。
面倒なんて言わずに、最初からおとなしくfunctionにしておけばよかったのです…

教訓
同じjsファイルを再読み込みするのは良くない。

記事を共有

最近人気な記事