2016-02-05 97 views
12

我在Elm中構建了一個簡單的應用程序,它只顯示一個div的列表,並且我想添加無限滾動功能,每當頁面的最後一個div出現時添加新內容在視口中。Elm中的無限滾動

在Elm中有一種方法可以知道div在視口中何時出現?作爲替代方法,在那裏可以跟蹤鼠標滾動事件作爲信號嗎?

回答

14

目前沒有滾動事件的Elm支持,所以你必須訴諸使用端口。這是一個簡單的例子。

我們需要一個javascript函數來告訴我們列表中最後一個元素是否在視圖端口中。我們可以從this StackOverflow answerisElementInViewport代碼(在這裏複製以供將來參考):

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> 

你榆樹代碼可能有一個端口作爲一個信號告訴我們最後一項是否可見。

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的信號。