2016-02-05 32 views
12

Buduję prostą aplikację w wiązu, która pokazuje tylko listę elementów div pod drugą, i chciałbym dodać funkcję nieskończonego przewijania, aby dodawać nowe treści za każdym razem, gdy pojawi się ostatni div strony w oknie roboczym.Nieskończone przewijanie w wiązce

Czy istnieje sposób w Elm, aby wiedzieć, kiedy w okienku ekranu pojawi się symbol div? Alternatywnie, czy istnieje sposób śledzenia, jako sygnału, zdarzenia przewijania myszy?

Odpowiedz

14

Obecnie nie ma wsparcia Elm dla zdarzeń przewijania, więc będziesz musiał uciekać się do używania portów. Oto prosty przykład.

Potrzebujemy funkcji javascript, aby poinformować nas, czy ostatni element na liście znajduje się w porcie widoku. Możemy wziąć kod isElementInViewport z this StackOverflow answer (skopiowany tutaj na przyszłość):

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() */ 
    ); 
} 

Załóżmy, że HTML wygląda mniej więcej tak:

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

Kod Elm może mieć port działając jako sygnał aby powiedzieć nam, czy ostatni element jest widoczny.

port lastItemVisible : Signal Bool 

Teraz trzeba podłączyć kod portu po stronie JavaScript rzeczy. Ten kod będzie nasłuchiwać zdarzenia window.onscroll, a następnie sprawdź, czy ostatni element wewnątrz .wrapper div jest widoczny i wyślij odpowiedni sygnał.

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); 
    } 
}; 

Jeśli zamiast tego potrzebujesz tylko sygnału do śledzenia zdarzeń przewijania, there is a related StackOverflow answer here.