榆树无限卷轴

时间:2016-02-05 13:59:51

标签: javascript infinite-scroll elm

我正在Elm中构建一个简单的应用程序,只显示一个在另一个下面的div列表,我想添加无限滚动功能,每次在视口中出现页面的最后一个div时添加新内容。

榆树中有没有办法知道div在视口中出现的时间?作为替代方案,有一种方法可以跟踪鼠标滚动事件作为信号吗?

1 个答案:

答案 0 :(得分:14)

目前没有Elm支持滚动事件,因此您不得不求助于使用端口。这是一个简单的例子。

我们需要一个javascript函数来告诉我们列表中的最后一个元素是否在视口中。我们可以从this StackOverflow answer获取isElementInViewport代码(此处复制以供将来参考):

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