この記事はアピリッツの技術ブログ「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ファイルを再読み込みするのは良くない。