2016-02-05 4 views
12

Я создаю простое приложение в Elm, которое показывает только список divs один под другим, и я хотел бы добавить бесконечную функциональность прокрутки, добавлять новый контент каждый раз, когда появляется последний div страницы в окне просмотра.Бесконечный свиток в Elm

Есть ли способ в Вяз узнать, когда в окне просмотра появляется div? В качестве альтернативы, есть способ отслеживать, как сигнал, событие прокрутки мыши?

ответ

14

В настоящее время нет поддержки Elm для событий прокрутки, поэтому вам придется прибегать к использованию портов. Вот простой пример.

Нам нужна функция javascript, чтобы сообщить нам, есть ли последний элемент в списке в порт представления. Мы можем взять isElementInViewport код из this StackOverflow answer (скопированный здесь для дальнейшего использования):

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> 

Ваш код Elm может иметь порт выступает в качестве сигнала чтобы узнать, отображается ли последний элемент.

port lastItemVisible : Signal Bool 

Теперь вам нужно подключить код порта на стороне JavaScript. Этот код будет прослушивать событие window.onscroll, а затем проверить, отображается ли последний элемент внутри div .wrapper и отправить соответствующий сигнал.

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.