第一件事已经开始了 (target="_new")。
The target should actually be _blank.
如何在第一个停止工作的情况下实现第二个(更新链接点击次数的方法调用)?
最简单(幼稚)的 JSF 方式是在点击时触发 <p:remoteCommand>。
<h:outputLink value="#{item.url}" target="_blank" onclick="count_#{item.id}()">
...
</h:outputLink>
<p:remoteCommand name="count_#{item.id}" action="#{likeditems.itemLinkClicked(item)}" />
但这会产生大量重复的 JS 代码,效果不佳。您可以将其放在数据列表之外并摆弄函数参数。但是,当最终用户右键单击并选择上下文菜单项(在新选项卡、新窗口、新隐身窗口中打开、另存为、复制地址等)时,这仍然不起作用。这在最终用户中间点击时也不起作用(中间点击的默认浏览器行为是“在新窗口中打开”)。
在ZEEF,我们使用脚本将点击、中键或右键单击时的<a href> 更改为一个URL,该URL 调用一个更新计数的servlet,然后在给定的URL 上执行window.open()。
给定一个
<h:outputLink value="#{item.url}" styleClass="tracked" target="_blank">
相关的脚本基本上应该是这样的:
// Normal click.
$(document).on("click", "a.tracked", function(event) {
var $link = $(this);
updateTrackedLink($link);
var trackingURL = $link.attr("href");
$link.attr("href", $link.data("href"));
$link.removeData("href");
window.open(trackingURL);
event.preventDefault();
});
// Middle click.
$(document).on("mouseup", "a.tracked", function(event) {
if (event.which == 2) {
updateTrackedLink($(this));
}
});
// Right click.
$(document).on("contextmenu", "a.tracked", function(event) {
updateTrackedLink($(this));
});
// Update link href to one of click count servlet, if necessary.
function updateTrackedLink($link) {
if ($link.data("href") == null) {
var url = $link.attr("href");
$link.data("href", url);
$link.attr("href", "/click?url=" + encodeURIComponent(url));
}
}
click servlet 应该如下所示(为简洁起见,省略了请求参数验证):
@WebServlet("/click")
public class ClickServlet extends HttpServlet {
@EJB
private ClickService clickService;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String url = request.getParameter("url");
clickService.incrementClickCount(url);
response.sendRedirect(url);
}
}
请注意,这种方式不需要target="_blank"。它只会被禁用 JavaScript 的用户使用。但是网站上还有很多其他的东西无论如何都不起作用,包括上面的 JS 跟踪。这也是你关心的问题,那你最好把那个click servlet URL直接放在<h:outputLink value>中。