我正在使用JSF w / Seam开发一个Web应用程序。我希望能够在每次ajax响应后调用JavaScript函数。我正在寻找一种方法来做到这一点,而不是在每个页面上的每个commandLink / commandButton上放置一个oncomplete属性。
我认为有一种方法可以设置一个servlet过滤器(拦截器?我的术语混淆),将JS调用注入每个响应。我要调查一下。与此同时,如果有人有任何其他建议,我会全力以赴。
编辑:我认为jQuery ajaxSuccess方法可能是这里的方法,但我不确定如何实际使用它。我无法注册任何东西。我基本上想要添加代码来从任何来源获取任何和所有ajax请求,以便成功调用我的JavaScript方法。有人能告诉我这样做的正确方法吗?我尝试了很多方法,包括将jQuery("*").ajaxSuccess(function(){myFunction();});
添加到我的模板xhtml文件的底部。
答案 0 :(得分:4)
重写回答: see original answer in revision history
您可以使用劫持send
处理程序的方法覆盖XMLHttpRequest
的默认readystatechange
方法:
(function ()
{
var xhrSend = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.send = function ()
{
var handler = this.onreadystatechange;
this.onreadystatechange = function ()
{
if (handler) {
if (handler.handleEvent) handler.handleEvent.apply(xhr, arguments);
else handler.apply(xhr, arguments);
}
if (this.readyState == 4)
{
// your oncomplete function here
this.onreadystatechange = handler;
}
};
xhrSend.apply(this, arguments);
};
})();
编辑:上述功能不适用于jQuery请求,因此可能会因其他库而失败。下面的修订解决了setTimeout
hack延迟覆盖处理程序的代码的问题。当然,使用jQuery,您可以使用.ajaxSuccess()
全局处理程序,但对于具有类似行为的其他库,这将非常有用。
(function() {
function globalHandler() {
if (this.readyState == 4) {
// your oncomplete code here
}
}
var xhrSend = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.send = function() {
var xhr = this;
if (xhr.addEventListener) {
xhr.removeEventListener("readystatechange", globalHandler);
xhr.addEventListener("readystatechange", globalHandler, false);
}
else {
function readyStateChange() {
if (handler) {
if (handler.handleEvent)
handler.handleEvent.apply(xhr, arguments);
else
handler.apply(xhr, arguments);
}
globalHandler.apply(xhr, arguments);
setReadyStateChange();
}
function setReadyStateChange() {
setTimeout(function() {
if (xhr.onreadystatechange != readyStateChange) {
handler = xhr.onreadystatechange;
xhr.onreadystatechange = readyStateChange;
}
}, 1);
}
var handler;
setReadyStateChange();
}
xhrSend.apply(xhr, arguments);
};
})();
http://jsfiddle.net/gilly3/FuacA/5/
我在IE7-9以及最新版本的Chrome和FF
答案 1 :(得分:3)
由于您使用的是RichFaces,您只需使用它:
<a:status id="globalStatus" onstart="onRequestStart()" onstop="onRequestEnd()" />
答案 2 :(得分:2)
使用a4j:状态应该有效,但必须在h:form标签内:
<h:form id="randomForm" styleClass="edit">
<a:status id="stateStatus"
onstart="Richfaces.showModalPanel('waitBx'),document.getElementById('randomForm:search').disabled=true;"
onstop="Richfaces.hideModalPanel('waitBx'),document.getElementById('randomForm:search').disabled=false;"
styleClass="message" >
</a:status>
...... way more code
</form>
每次ajax调用后,会弹出一张等待图片并禁用搜索按钮。
有趣的是,至少在我们的代码中,这对嵌套的a4j:region中的任何内容都不起作用。
答案 3 :(得分:1)
我认为这正是您所寻找的:Using Global Ajax Handlers In jQuery