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

ian*_*sme 4 javascript jquery seam ajax4jsf

我正在使用带有Seam的JSF的Web应用程序。我希望能够在每个ajax响应后调用JavaScript函数。我正在寻找一种无需在每个页面的每个commandLink / commandButton上放置oncomplete属性的方法。

我认为有一种方法可以设置一个servlet过滤器(拦截器?让我感到困惑),将JS调用注入每个响应中。我将对此进行调查。在此期间,如果有人有其他建议,我会非常高兴。

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

gil*_*ly3 5

重写答案: 在修订历史记录中查看原始答案

您可以使用劫持处理程序的默认send方法来覆盖默认方法:XMLHttpRequestreadystatechange

(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); 
    }; 
})(); 
Run Code Online (Sandbox Code Playgroud)

编辑:上面的功能不适用于jQuery请求,因此可能会因其他库而失败。下面的修订版通过setTimeout破解来延迟覆盖处理程序的代码,从而解决了该问题。当然,使用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);
    };
})();
Run Code Online (Sandbox Code Playgroud)

http://jsfiddle.net/gilly3/FuacA/5/
我在IE7-9和最新版本的Chrome和FF中进行了测试