开发者

Can I use jQuery prefilters to detect onreadystatechange events where readyState==3?

I'm trying to implement the XHR streaming Comet technique in jQuery, but am having some trouble detecting the onreadystatechange event. I'm using Firefox 4.0.1.

I'm using prefilters (available since jQuery 1.5) to modify the native XHR object, specifically to add an event handler to the onreadystatechange event. I've got a crude implementation of that at http://jsfiddle.net/Rdx6f/. That code appends to the document the XHR object's readyState and responseText attributes when the onreadystatechange event is fired. Oddly, h开发者_如何转开发owever, it only seems to detect the onreadystatechange event when readyState is 1.

In other words, jQuery seems to be detecting the onreadystatechange event when the XMLHttpRequest object is in state "opened" (readyState 1), but not when the XHR object is in state "headers received" (readyState 2), "loading" (readyState 3), nor "done" (readyState 4).

Oddly, if I alert() in the event handler, then I do see the onreadystatechange handling when readyState is 1, 2, 3 and 4. See http://jsfiddle.net/Rdx6f/1/. Same code as http://jsfiddle.net/Rdx6f/, just alert()ing instead of appending to the document.

I can also detect onreadystatechange events when readyState is 1, 2, 3 or 4 in native JavaScript -- see http://jsfiddle.net/d7vaH/. (That code is taken almost verbatim from Dylan Schiemann's implementation of XHR streaming on page 115 of the book "Even Faster Websites".)

Am I simply doing something wrong here, like using jQuery's Ajax prefilters wrong or making a JavaScript mistake? Is this perhaps a bug in jQuery?


FYI: I looked into this quite deeply and it turns out that jQuery (since 1.5) uses the onreadystatechange event internally. The consequence of this is that jQuery will always write it's internal function to the onreadystatechange event, overwriting whatever you set it to. This happens whenever the AJAX call is actually sent, which means the function you wrote for onreadystatechange will work until that time (which means it will work until readyState = 1, but not longer).

This is the proposed workaround at the moment: http://jsfiddle.net/tBTW2/

At the moment, I cannot see a different (better) workaround without either not using jQuery (or going back to 1.4.4 or lower version, where it works perfectly) or editing the jQuery code (because as it is right now they will always overwrite whatever you try to hook in).

However, in upcoming versions (most likely in 1.8), the jQuery team are planning on implementing support for triggering events depending on the different readyStates. They will use Deferreds in some way.

This is the ticket that keeps this upcoming change:

http://bugs.jquery.com/ticket/9883


Here is the prefiltering done correctly linked from the jQuery bugzilla bug #8327,

http://jsfiddle.net/d8ckU/1/

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜