如何在每次a4j AJAX响应后调用JavaScript函数?

时间:2011-10-26 21:03:20

标签: javascript jquery seam ajax4jsf

我正在使用JSF w / Seam开发一个Web应用程序。我希望能够在每次ajax响应后调用JavaScript函数。我正在寻找一种方法来做到这一点,而不是在每个页面上的每个commandLink / commandButton上放置一个oncomplete属性。

我认为有一种方法可以设置一个servlet过滤器(拦截器?我的术语混淆),将JS调用注入每个响应。我要调查一下。与此同时,如果有人有任何其他建议,我会全力以赴。

编辑:我认为jQuery ajaxSuccess方法可能是这里的方法,但我不确定如何实际使用它。我无法注册任何东西。我基本上想要添加代码来从任何来源获取任何和所有ajax请求,以便成功调用我的JavaScript方法。有人能告诉我这样做的正确方法吗?我尝试了很多方法,包括将jQuery("*").ajaxSuccess(function(){myFunction();});添加到我的模板xhtml文件的底部。

4 个答案:

答案 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