mar*_*osh 12 javascript infinite-scroll elm
我正在Elm中构建一个简单的应用程序,只显示一个在另一个下面的div列表,我想添加无限滚动功能,每次页面的最后一个div出现在视口中时添加新内容.
在Elm中有没有办法知道div何时出现在视口中?作为替代方案,有一种方法可以跟踪鼠标滚动事件作为信号吗?
Cha*_*ert 14
目前没有Elm支持滚动事件,因此您将不得不求助于使用端口.这是一个简单的例子.
我们需要一个javascript函数来告诉我们列表中的最后一个元素是否在视口中.我们可以isElementInViewport从这个StackOverflow答案中获取代码(复制到这里以供将来参考):
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() */
);
}
Run Code Online (Sandbox Code Playgroud)
假设您的HTML看起来像这样:
<div class="wrapper">
<div class="item">...</div>
<div class="item">...</div>
</div>
Run Code Online (Sandbox Code Playgroud)
您的Elm代码可以有一个端口充当信号,告诉我们最后一项是否可见.
port lastItemVisible : Signal Bool
Run Code Online (Sandbox Code Playgroud)
现在你需要在Javascript方面连接端口代码.此代码将侦听window.onscroll事件,然后检查.wrapperdiv中的最后一项是否可见,并发送相应的信号.
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);
}
};
Run Code Online (Sandbox Code Playgroud)
如果你只想要一个跟踪滚动事件的信号,这里有一个相关的StackOverflow答案.