当任何 ajax 请求完成时触发事件

发布于 2025-01-04 05:57:55 字数 149 浏览 0 评论 0原文

我希望监听来自各个请求本身之外的所有 ajax 请求的 onComplete 事件。

我想在任何/所有 ajax 请求完成时触发一个事件。

这可能吗?

提前致谢,蒂姆

编辑:仅要求 mootools lib (v1.4)

I am looking to listen to the onComplete event from all ajax requests from outside of the individual requests themselves.

I would like to fire an event when any/all ajax requests complete.

Is this possible?

Thanks in advance, Tim

Edit: requirements mootools lib only (v1.4)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

绝影如岚 2025-01-11 05:57:55

如果您只想观察并拦截,这可能会很棘手。代码非常简单。我对单个请求原型更改的选择是来自 mootools-more 的 Class.refactor(如果可用):

// enable log func...
Class.refactor(Request, {
    success: function(text, xml){
        this.previous(text, xml);
        Request.monitor && typeof Request.monitor == "function" && Request.monitor.apply(this, arguments);            
    },
    failure: function(){
        this.previous();
        Request.monitor && typeof Request.monitor == "function" && Request.monitor.apply(this, arguments);            
    }
});

以及通用位 - 无论您采用哪种方式,这都是相同的。

// assign a logger function
Request.monitor = function() {
    console.log("onComplete", this.response.text);
};

// call a simple request object.   
new Request({
    url: "/echo/html/",
    method: "post",
    data: {
        html: "hello"
    }
}).send();

原因是:它将独立于 mootools-core 的更改而工作。它不关心 func 代码是什么,它会在原始代码之后运行我们的代码并且不会中断,除非将来有巨大 api 更改

您也可以通过 implement 相反,尽管这不会考虑 mootools-core 中的更改,无论这种情况有多么可能。实际上,这意味着,复制并粘贴方法中的当前函数并添加到其中 - 幸运的是,我们想要修改短方法:

Request.implement({
    success: function(text, xml){
        this.onSuccess(this.processScripts(text), xml);
        Request.monitor && typeof Request.monitor == "function" && Request.monitor.apply(this, arguments);            
    },
    failure: function(){
        this.onFailure();
        Request.monitor && typeof Request.monitor == "function" && Request.monitor.apply(this, arguments);            
    }
});

最后,您甚至可以保存旧的低级别 var oldsuccess = Request.prototype.success< /code>,做你的事情并oldsuccess.apply(this,arguments)它。

困难在于,像 HTML 和 JSON 这样的 Request 子类 - 如果已经定义,它们将复制旧的原型,而您的记录器现在不会这样做。您可以将其作为一个小对象来执行,并将其实现到所有 Request 类中。

这样的东西很优雅并且可以工作,但前提是成功方法在代码中相同,否则 - 它会破坏子类中的内容:

(function() {
    var changes = {
        success: function(text, xml){
            this.onSuccess(this.processScripts(text), xml);
            Request.monitor && typeof Request.monitor == "function" && Request.monitor.apply(this, arguments);            
        },
        failure: function(){
            this.onFailure();
            Request.monitor && typeof Request.monitor == "function" && Request.monitor.apply(this, arguments);            
        }
    };

    [Request, Request.HTML, Request.JSON].invoke('implement', changes);
})();

最后一个方法+原始原型的组合才是你真正需要的,因为所有 3 个方法的成功函数都不同...

编辑这太荒谬了。就像我说的,这不是最简单的任务...

这可能是我在生产、测试​​和使用所有 3 个类时使用的最终版本/重构。请记住,完成的方法是在对 JSON 或 HTML 进行额外解析之前进行的。这是低级日志记录。否则,重构为继续 onSuccess 和 onFailure。

(function() {
    // what we will extend
    var classes = [Request, Request.HTML, Request.JSON],
        // map to a text name
        mapper = ["Request", "Request.HTML", "Request.JSON"],
        // store reference to original methods
        orig = {
            onSuccess: Request.prototype.onSuccess,
            onFailure: Request.prototype.onFailure
        },
        // changes to protos to implement
        changes = {
            onSuccess: function(){
                Request.Spy && typeof Request.Spy == "function" && Request.Spy.apply(this, arguments);
                orig.onSuccess.apply(this, arguments);
            },
            onFailure: function(){
                Request.Spy && typeof Request.Spy == "function" && Request.Spy.apply(this, arguments);
                orig.onFailure.apply(this, arguments);
            }
        };

    classes.invoke('implement', changes);

    // allow us to tell which Class prototype has called the ajax
    Request.implement({
        getClass: function() {
            var ret;
            Array.each(classes, function(klass, index) {
                if (instanceOf(this, klass)) {
                    ret = mapper[index];
                }
            }, this);
            return ret;
        }
    });
})();

// to enable spying, just define Request.Spy as a function:
Request.Spy = function() {
    console.log(this.getClass(), arguments);
};

// test it via normal Request
new Request({
    url: "/echo/html/",
    data: {
        html: "normal data"    
    }
}).send();


// test via HTML
new Request.HTML({
    url: "/echo/html/",
    data: {
        html: "<p>normal data</p>"    
    }
}).send();

// test via JSON
new Request.JSON({
     url: "/echo/json/",
     data: {
        json: JSON.encode({'normal':'data'})    
     }
}).send();

jsfiddle: http://jsfiddle.net/dimitar/3rnKe/

This can be tricky if you want to observe and intercept only. The code is quite simple. my choice for a single Request proto change would be Class.refactor from mootools-more, if available:

// enable log func...
Class.refactor(Request, {
    success: function(text, xml){
        this.previous(text, xml);
        Request.monitor && typeof Request.monitor == "function" && Request.monitor.apply(this, arguments);            
    },
    failure: function(){
        this.previous();
        Request.monitor && typeof Request.monitor == "function" && Request.monitor.apply(this, arguments);            
    }
});

and the common bit - this is the same whichever way you go.

// assign a logger function
Request.monitor = function() {
    console.log("onComplete", this.response.text);
};

// call a simple request object.   
new Request({
    url: "/echo/html/",
    method: "post",
    data: {
        html: "hello"
    }
}).send();

The reason: it will work independently of mootools-core changes. It does not care what the func code is, it will run ours after the original and will not break, unless there's a huge api change in the future

You can also change classes through implement instead, though this won't account for changes in mootools-core, however likely that may be. in practice that means, copy and paste current func in the methods and add to it - luckily, short methods we want to mod:

Request.implement({
    success: function(text, xml){
        this.onSuccess(this.processScripts(text), xml);
        Request.monitor && typeof Request.monitor == "function" && Request.monitor.apply(this, arguments);            
    },
    failure: function(){
        this.onFailure();
        Request.monitor && typeof Request.monitor == "function" && Request.monitor.apply(this, arguments);            
    }
});

And finally, you can even save the old low level var oldsuccess = Request.prototype.success, do your thing and oldsuccess.apply(this, arguments) it.

The difficulty is, subclasses of Request like HTML and JSON - if already defined, they will have copied the old prototype and your logger will do nowt. you can instead do this as a small object and implement it into all Request classes.

Something like this is elegant and could work but only if the success methods are the same in code, else - it will break stuff in subclasses:

(function() {
    var changes = {
        success: function(text, xml){
            this.onSuccess(this.processScripts(text), xml);
            Request.monitor && typeof Request.monitor == "function" && Request.monitor.apply(this, arguments);            
        },
        failure: function(){
            this.onFailure();
            Request.monitor && typeof Request.monitor == "function" && Request.monitor.apply(this, arguments);            
        }
    };

    [Request, Request.HTML, Request.JSON].invoke('implement', changes);
})();

a combo of last method + orig proto is what you really need as the success funcs differ across all 3...

edit this is getting ridiculous. like i said, not the easiest task...

this would probably be the final version / refactor I'd use in production, tested and working with all 3 classes. Keep in mind the methods done are BEFORE the extra parsing for JSON or HTML take place. it's low level logging. else, refactor to go after onSuccess and onFailure instead.

(function() {
    // what we will extend
    var classes = [Request, Request.HTML, Request.JSON],
        // map to a text name
        mapper = ["Request", "Request.HTML", "Request.JSON"],
        // store reference to original methods
        orig = {
            onSuccess: Request.prototype.onSuccess,
            onFailure: Request.prototype.onFailure
        },
        // changes to protos to implement
        changes = {
            onSuccess: function(){
                Request.Spy && typeof Request.Spy == "function" && Request.Spy.apply(this, arguments);
                orig.onSuccess.apply(this, arguments);
            },
            onFailure: function(){
                Request.Spy && typeof Request.Spy == "function" && Request.Spy.apply(this, arguments);
                orig.onFailure.apply(this, arguments);
            }
        };

    classes.invoke('implement', changes);

    // allow us to tell which Class prototype has called the ajax
    Request.implement({
        getClass: function() {
            var ret;
            Array.each(classes, function(klass, index) {
                if (instanceOf(this, klass)) {
                    ret = mapper[index];
                }
            }, this);
            return ret;
        }
    });
})();

// to enable spying, just define Request.Spy as a function:
Request.Spy = function() {
    console.log(this.getClass(), arguments);
};

// test it via normal Request
new Request({
    url: "/echo/html/",
    data: {
        html: "normal data"    
    }
}).send();


// test via HTML
new Request.HTML({
    url: "/echo/html/",
    data: {
        html: "<p>normal data</p>"    
    }
}).send();

// test via JSON
new Request.JSON({
     url: "/echo/json/",
     data: {
        json: JSON.encode({'normal':'data'})    
     }
}).send();

jsfiddle: http://jsfiddle.net/dimitar/3rnKe/

小梨窩很甜 2025-01-11 05:57:55

编辑:解决方案适用于 jQuery。不是 MooTools。

$(document).ajaxComplete(function() {
  $(this).text('Triggered ajaxComplete handler.');
});

看一下: http://api.jquery.com/ajaxComplete/

EDIT: Solution works for jQuery. NOT MooTools.

$(document).ajaxComplete(function() {
  $(this).text('Triggered ajaxComplete handler.');
});

Take a look at: http://api.jquery.com/ajaxComplete/

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文