今回の例では、BootstrapとjQueryを使用します。
1.Bootstrapで読み込めるmodalを作成します。
HTMLを用意します。
※一部だけ参考に載せています。
modal.html
<div class="modal fade " id="scoreReportModal" tabindex="-1" role="dialog" aria-hidden="true" data-keyboard="false" data-backdrop="static">
<div class="modal-dialog">
<div class="modal-content" style="min-height: 500px;">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"><span class="icon icon-modal-close"></span></button>
</div>
<!-- CSSは割愛するのでここでstyleを定義 -->
<!-- 大事なのは、position: fixed; overflow-y: scroll; -->
<div class="modal-body" style="position: fixed;top: 100px;right: auto;bottom: 0;left: auto;overflow-y: scroll;">
<table class="table">
<thead>
<tr>
<th>ナンバー</th>
<th>名前</th>
<th>スコア</th>
<th>更新日</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>A君</td>
<td>90点</td>
<td>2015/12/21</td>
</tr>
<tr>
<td>2</td>
<td>B君</td>
<td>80点</td>
<td>2015/12/20</td>
</tr>
<tr>
<td>3</td>
<td>C君</td>
<td>60点</td>
<td>2015/12/21</td>
</tr>
<tr>
<td>4</td>
<td>D君</td>
<td>100点</td>
<td>2015/12/19</td>
</tr>
</tbody>
<div class="modal-footer">
<p id="scoreNext" data-next="1" class="" style="display: none;"></p>
</div>
</table>
</div>
</div>
</div>
</div>
スクロールしたい箇所の要素に、
ポジションを固定し、position: fixed;
はみ出た内容はスクロールするように指定します。overflow-y: scroll;
2.モーダル開く処理と、スクロールイベントの監視
load.js
$(function() {
/**
* スコアボードを開く処理
*/
$(document).on('click', '#openScoreBoard', function(){
// next初期化
$('#scoreNext').attr('data-next', 1).text('');
// tbody初期化
var tbody = $('#scoreReportModal').find('.modal-body > table > tbody');
tbody.find('tr').remove();
getScore($(this));
});
// modal-bodyの中身がスクロールされたら
$('#scoreReportModal').find('.modal-body').scroll(function(ev) {
scrollHeight = $(this).find('tbody').height();
scrollPosition = $(this).height() + $(this).scrollTop();
// 比較対象の0の値は適宜変更して下さい。
if ( (scrollHeight - scrollPosition) / scrollHeight <= 0) {
// 最下部までスクロールしたらデータの取得
getScore($('#openScoreBoard'));
}
});
});
modal-bodyの中身のスクロールを監視する。
3.Ajaxでデータ取得
load.js
/* 複数通信制御用のフラグ */
var isConnecting = false;
function getScore(obj) {
if (!isConnecting) {
var next = $('#scoreNext');
// 次のデータがなければ処理終了
if (next.attr('data-next') == 0) {
return;
}
var url = obj.attr('data-url') + '/' + next.text();
// ajax
isConnecting = true;
$.ajax({
type : "GET",
url: url,
dataType: "json",
success: function(m) {
var scoreModal = $('#scoreReportModal');
var tbody = scoreModal.find('.modal-body > table > tbody');
var count = m.score.length;
if (count) {
for (var i in m.score) {
// ココらへんでデータをsetするとか
}
} else {
// データがありません
tbody.find('tr').eq(0).append('<tr><td colspan="4" align="center">データがありません。</td></tr>');
}
if (scoreModal.css('display') == 'none') {
// modalの表示
scoreModal.modal('show');
}
// 1ページ目ならスクロール位置更新
if (next.text() == 1) {
$('#scoreReportModal').find('.modal-body').animate({scrollTop: 0}, 800);
}
// nextパラメータ
next.attr('data-next', m.isNext);
next.text(m.next);
},
error : function() {
// エラー処理
openAlertModal(lang_ajax_error);
},
complete : function () {
// フラグを落とします
isConnecting = false;
}
});
}
}
まとめ
スクロールTOPに戻すやつ、
$('#scoreReportModal').find('.modal-body').animate({scrollTop: 0}, 800);
↓なんでこれだと動かないのかわからなかった。(Chrome)
$('#scoreReportModal').find('.modal-body').scrollTop(0);
全体的に確実にもっとシンプルになりますよね・・・(;・∀・)
フレームワークの導入を考えた方が良さそうです・・・。
業務系のwebアプリケーションで採用されているおすすめフレームワークって何だろう??