Ditto を使って Ajax で「もっと読む」「さらに見る」のリンクを実装します。
Ditto と Ajaxで「もっと読む」を簡単に実装する
- 最終更新日
- 2017.10.15
移行作業中のため一部のページが正しく表示されていない場合があります(o-ω-))
例でリソースのツリーは以下のようになっているものとして商品情報以下のリソースを取得する。
手順
一覧用リソースの作成
商品情報一覧ページ(ID:2)
のリソースに最初から表示しておく一覧用の Ditto スニペットコードを書く。
<ul class="moreload_pagelist">
[[Ditto?
&id=`more`
&parents=`2`
&display=`4`
&paginate=`1`
&tpl=`@CODE: <li><a href="[+url+]">[+title+]<br>登録日: [+date+]</a></li>`
]]
</ul>
ページネーション機能&paginate
を有効にしてプレースホルダを使えるようにしておく。
Ditto は JSON も出力できるので取得してからレイアウトする API 的な使い方も可能ですが、今回はなるべく手軽に実装するため HTML を取得する Pjax ライクな表示方法にしている。
一覧ページにもっと読むリンクを作成
上記の一覧用リソースの下側に、ページリンクの代わりに「もっと読む」用のリンクを記述。@IFタグを使って1ページしか無ければなにも表示しないようにしている。
<!--@IF:![+more_totalPages:el(1)+]-->
<div class="moreload_more link" data-totalpages="[+more_totalPages+]" data-perpage="[+more_perPage+]" data-current="[+more_currentPage+]">
<a href="#" class="link">もっと読む</a><span class="indicator">loading...</span>
</div>
<!--@ENDIF-->
あとで説明する JavaScript では Ajax ロード中は.moreload_more
クラスに.loading
クラスを追加するようにするため、これを利用してロード中なら.moreload_more .loading
を表示、それ以外の時は.moreload_more .link
を表示するようにしている。
.moreload_more { border: 1px solid #ccc; padding: 10px; background: #f5f5f5; text-align: center; }
.moreload_more .link, .moreload_more.loading .indicator { display:block; }
.moreload_more .indicator, .moreload_more.loading .link { display:none; }
Ajax用 リソースの作成
次に Ajax 取得先のリソース(ID:37)
を作成する。Ditto はデフォルトで非公開以下のリソースを表示しないので非公開フォルダを作りその中にリソース「ajax.html」を作成。このリソースはテンプレートを(blank)に設定して Ditto のみを表示するようにしておく。
「商品情報/app/ajax.html」の中身は以下のとおりで<ul></ul>
を省いた以外は HTML に書いたものと同じ。全く同じなのでテンプレートが長ければチャンク化しても良いです。
[[Ditto?
&id=`more`
&parents=`2`
&display=`4`
&paginate=`1`
&tpl=`@CODE: <li><a href="[+url+]">[+title+]<br>登録日: [+date+]</a></li>`
]]
このリソース自体にアクセスしてページネーション表示されるか確認してみてください。
Ajax用 JavaScriptの作成
jQuery を使用するので jQuery 本体を読み込んでおく。
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
以下サンプルで作成したシンプルな Ajax ロード用の JavaScript コード。
$(function() {
// ajax用リソースのURL
var durl = 'news/app/ajax.html';
// 結果を表示するコンテナのクラス名
var e_name_container = '.moreload_pagelist';
// もっと読む表示用のコンテナセレクタ。このセレクタの中にもっと読むリンク「.link」を入れます。
var e_name_more = '.moreload_more';
$(e_name_more + ' .link').on('click', function(event) {
event.preventDefault();
var eMore = $(e_name_more);
$.ajax({
url: durl + "?more_start=" + parseInt(eMore.attr('data-perpage') * eMore.attr('data-current')),
dataType: "html",
beforeSend: function () {
eMore.addClass('loading');
}
}).done(function(data) {
// 記事を表示するアニメーションはここらへんで調整
$(data).hide().css({
opacity: 0
}).appendTo(e_name_container).slideDown('fast').animate({
opacity: 1
}, function() {
eMore.removeClass('loading');
});
eMore.attr('data-current', parseInt(eMore.attr('data-current')) + 1);
// 読み込む記事がなくなったらmoreを非表示
if (eMore.attr('data-current') > eMore.attr('data-totalpages') - 1) {
eMore.hide();
}
}).fail(function(a, b, c) {
console.log(c);
eMore.removeClass('loading');
});
});
});
読み込むタイミングをクリックから.moreload
のスクロール位置(表示位置)に変えてにょごにょしたら Twitter みたいにスクロールしたら勝手に読みこむ感じに出来そう。
まとめ
そして今更なんですけど実はこのタイプの読み込み方法は個人的にはあまり好きではない。
数ページ分読み込んでから記事を読んでブラウザで戻るとまた最初からロードしないといけなかったり、そのページ分一覧の URL が取得できない、というのがとても不便に感じます。実際に使う場合はもう少しユーザビリティを考慮した形にするといいかも。
例えばはてなブックマークのように通常のページネーションと両実装させるやり方は使いやすいと思います。また時間がある時にそのへんも考慮したサンプルを書きたいなーと思ってます。