Autopagerizeとかendless scrollingみたいなやつ,下につぎ足すから,気付かないうちに下に記事が増えている,ということができる.
けど,上につぎたすと,スクロールの位置がずれてうっとおしい感じになる.
上につぎたしたあと,ずれたスクロールを戻す必要がある.
上のほうに400ピクセルの高さの要素をつぎたすと,400ピクセル上にスクロールしてしまうから,つぎたしたあとに,400ピクセル下にスクロールして,見ていた場所に戻す必要がある.
つぎたした要素に画像が入っていたりすると,あとで画像の読み込みが終わって,高さが変わってしまうから,そういうのがある場合は,読み込みを待ってからつぎたす必要がある.
昨日やってみて,けっこう難しかった.まだうまく動かなかったりする.
画像の読み込みを待つのこういう感じ.画像がないときはすぐに実行するのを忘れると実行されない.最大で1秒しか待たないとかやってもいいと思う.
waitForLoadImages = (element, callback) ->
images = $(element).find('img')
if images.length == 0
callback(element)
return
count = 0
images.each ->
image = $(this)
image.load ->
count++
if count == images.length
callback(element)
スクロールするやつ.
つぎたす前にcheckScrollを読んでおいて,つぎたして,座標が再計算されてからlaterの中が実行されて,座標が変わってるはずだから,変わった分だけ戻す.
いくつも連続して呼び出すとスクロールしすぎるから,debounceして,かつ,最初の実行は同期的にする.laterはsetTimeout 0.
checkScroll = debounce ->
entry = $('#main-inner article:last')
return unless entry.length
top_before = entry.position().top
later ->
top_after = entry.position().top
window.scrollBy(0, top_after - top_before)
, 100, true
がんばって書いたけど,こういうのをやるライブラリとかあってもいい気がする.もっといい方法があると思う.
twitterとか,はてなハイクとかは,「新着が○件あります」とか出てきて,クリックすると読み込まれるようになっている.
あと,こういうのも書いた.呼び出された分はやるけど,最大でも1秒に1回しか実行されない.
UIイベントにフックしてリクエスト投げるときに使える.ユーザーがクリックしまくると大量にリクエスト投げるということになると困る.
これだとキューは1つだけできるけど,createQueue()すると新しいのを作って返すとかにしてもいいと思う.
executeByQueue = do ->
queue = []
timer = null
(func) ->
if timer
queue.push func
return
else
timer = setInterval ->
if queue.length > 0
queue.shift()()
else
clearInterval(timer)
timer = null
, 1000
func()