我正在尝试在 jQuery Waypoint 和 Masonry API 的帮助下使用 Primefaces 来实现无限滚动。
这是我到目前为止所拥有的:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://xmlns.jcp.org/jsf/html" xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets" xmlns:p="http://primefaces.org/ui" xmlns:pe="http://primefaces.org/ui/extensions">
<f:view>
<h:head>
<h:outputScript library="primefaces" name="jquery/jquery.js" />
<h:outputScript name="js/global.js"/>
<h:outputScript name="js/masonry.pkgd.js"/>
<h:outputScript name="js/imagesloaded.pkgd.js"/>
<h:outputStylesheet name="css/global.css" />
<title>Gallery</title>
</h:head>
<h:body>
<h:form prependId="false">
<h:panelGroup id="galleryPanel" layout="block">
<p:outputPanel autoUpdate="true">
<h:panelGroup layout="block" styleClass="galleryContainer">
<ui:repeat id="gallery" value="#{galleryController.images}" var="image">
<h:panelGroup layout="block" styleClass="item">
<h:graphicImage library="images" name="demo/#{image}.jpg" />
</h:panelGroup>
</ui:repeat>
</h:panelGroup>
</p:outputPanel>
<pe:waypoint id="waypoint" widgetVar="waypointWidget" offset="function(){return $.waypoints('viewportHeight') - $(this).outerHeight()}">
<pe:javascript event="reached" execute="handleLoadStart(ext);"/>
</pe:waypoint>
<h:outputScript target="body">
var layout = function(){
var container = $('.galleryContainer');
$(container).imagesLoaded(function(){
$(container).masonry({
itemSelector : '.item',
columnWidth : 240
});
});
};
var handleLoadStart = function(ext) {
if (ext.direction == "down") {
PF('waypointWidget').remove();
moreMedia();
}
};
var handleLoadStop = function(){
layout();
PF('waypointWidget').register();
};
$(document).ready(function(){
layout();
});
</h:outputScript>
<p:remoteCommand name="moreMedia" update="gallery" actionListener="#{galleryController.loadMore}" oncomplete="handleLoadStop()"/>
</h:panelGroup>
</h:form>
</h:body>
</f:view>
</html>
托管 Bean 是:
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.IntStream;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.event.ActionEvent;
@ManagedBean(name="galleryController")
@ViewScoped
public class GalleryController implements Serializable {
private static final long serialVersionUID = 563439107531288284L;
private List<String> images;
@PostConstruct
public void initialize() {
images = new ArrayList<>();
IntStream.range(1, 16).forEach(i->images.add(new String("image" + i)));
}
public void loadMore(ActionEvent event){
IntStream.range(1, 16).forEach(i->images.add(new String("image" + i)));
}
public List<String> getImages() {
return images;
}
public void setImages(List<String> images) {
this.images = images;
}
}
它正在部分工作,因为它有问题。
主要问题是,当我将新图像添加到现有图像列表中时,它ui:repeat
会完全渲染。我不想这样做。因为通过这种方式,现有图像也会被加载。现代浏览器如 FF 或 Chome 缓存图像,所以这对他们来说不是问题,但在像 IE 这样的浏览器中,我可以在网络控制台中看到它正在发送 GET 来获取这些图像。从性能角度来看,不应获取已加载的图像,而应仅获取新添加的图像。
但我不知道如何在 JSF 中做到这一点!
同样作为副作用,砌体没有按预期工作。每次触发该方法onComplete
时,滚动条都会设置到顶部。从功能的角度来看,它应该停留在 Waypoint 触发下一次加载的位置。p:remoteCommand
layout()
任何建议都会非常有帮助。