2016-02-05 22 views
12

私はElmのdivのリストだけを表示する単純なアプリケーションを構築しています。無限のスクロール機能を追加して、ページの最後のdivが表示されるたびに新しいコンテンツを追加したいと思いますビューポートに表示されます。Elmの無限のスクロール

ビューポートにdivが表示されるタイミングをElmが知る方法はありますか?別の方法として、マウススクロールイベントをシグナルとして追跡する方法はありますか?

答えて

14

現在のところ、スクロールイベントのElmサポートはないので、ポートを使用する必要があります。ここに簡単な例があります。

リストの最後の要素がビューポートにあるかどうかを判断するにはjavascript関数が必要です。

function isElementInViewport (el) { 
    //special bonus for those using jQuery 
    if (typeof jQuery === "function" && el instanceof jQuery) { 
     el = el[0]; 
    } 

    var rect = el.getBoundingClientRect(); 

    return (
     rect.top >= 0 && 
     rect.left >= 0 && 
     rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /*or $(window).height() */ 
     rect.right <= (window.innerWidth || document.documentElement.clientWidth) /*or $(window).width() */ 
    ); 
} 

はのは、あなたのHTMLは次のようになりましょう:

<div class="wrapper"> 
    <div class="item">...</div> 
    <div class="item">...</div> 
</div> 

あなたのエルムコードが信号として動作するポートを持つことができ、我々は(今後の参考のためにここにコピー)this StackOverflow answerからisElementInViewportコードを取ることができます最後の項目が表示されているかどうかを教えてください。

port lastItemVisible : Signal Bool 

これで、Javascript側のポートコードを結びつける必要があります。このコードはwindow.onscrollイベントをリッスンし、.wrapper div内の最後の項目が表示されているかどうかを確認し、適切な信号を送信します。

var app = Elm.fullscreen(Elm.Main, { 
    lastItemVisible: false 
}); 

window.onscroll = function() { 
    var wrapper = document.getElementsByClassName("wrapper")[0]; 
    var lastItem = wrapper.childNodes[wrapper.childNodes.length - 1]; 

    if (isElementInViewport(lastItem)) { 
    app.ports.lastItemVisible.send(true); 
    } else { 
    app.ports.lastItemVisible.send(false); 
    } 
}; 

代わりにスクロールイベントをトラッキングする信号が必要な場合は、there is a related StackOverflow answer here

関連する問題