目的
個人的な事情。
MEANS環境でのjavascript開発を始めたが、どうもクライアント側のWEB開発がまだまだだ。特にAngularJSでDirectiveを作ってみたいもののjQuery力が決定的に足りない。とりあえず何か作ってみる。
なにをやるのか。
twitterのいわゆるTimelineのようなユルユルと自動スクロールするDirectiveがないようなので作ってみた。
(一番下まで手動でスクロールしたらサーバにデータを取りに行く、いわゆるLoadMoreのようなDirectiveは世の中にあるのですが、ユルユル型はありませんでした。簡単すぎるんでしょうね。)
ソース
かなり紆余曲折があったものの最終的にできたモノは非常にシンプル。
'use strict';
angular.module('thinglue.directives', [])
//.directive('autoScroll', function($window){
.directive('autoScroll', function($window,$document){
return function(scope){
scope.$watch(function(){
angular.element($window).scrollTop($document[0].body.scrollHeight - angular.element($window)[0].innerHeight);
//angular.element($window).scrollTop(angular.element($window).height());
});
};
});
使い方(例)
・app/scripts/directives/配下に上記ソースを保存。
・app/views/index.htmlでソースをインクルード。
・app/scripts/app.jsで上記モジュール名(myApp.directives)を指定。(これを忘れていて少しハマりました。Chrome用のAngularプラグインでDependencyグラフに自分が作成したDirectiveが表示されていないので気が付きました。)
・app/views/partial/myapp.htmlで使用。
<div auto-scroll >
<ul ng-repeat='item in list'>
<li >{{item.text}}</li>
</ul>
<div>
・Controller側で一定時間間隔で$scope.listのArrayに要素をPushしたらユルユルと自動スクロールする画面ができました。
感想
・結果的に非常にシンプルになりましたが、directiveの作り方やDOM内での現在のスクロール位置(angular.element(\$window)[0].body.pageYOffset)やウィンドウの高さ(\$document[0].body.scrollHeight )を地道に調べたりしてなかなか勉強になりました。
・今回はクライアント側の実装のみです。サーバ側のtwitter streaming APIをたたく部分はすでにNodeJS/Expressで作成していますが、残りはクライアント⇔サーバ間の通信をどうするのか。COMET(long polling)方式にするかWebSocket方式にするのか、いずれにしてもStatefullな実装になるので異常系を含めて考えると悩ましいところです。