我可以使用 jQuery 预过滤器来检测 readyState==3 的 onreadystatechange 事件吗?
我正在尝试在 jQuery 中实现 XHR 流式 Comet 技术,但在检测 onreadystatechange
事件时遇到一些问题。我使用的是火狐4.0.1。
我使用 prefilters (自 jQuery 1.5 起可用)来修改本机 XHR 对象,特别是向 onreadystatechange
事件添加事件处理程序。我在 http://jsfiddle.net/Rdx6f/ 上有一个粗略的实现。当触发 onreadystatechange
事件时,该代码会将 XHR 对象的 readyState
和 responseText
属性附加到文档中。然而奇怪的是,它似乎只在 readyState
为 1 时才检测到 onreadystatechange
事件。
换句话说,jQuery 似乎正在检测 onreadystatechange
事件当 XMLHttpRequest 对象处于“已打开”状态(readyState 1)时,但不是当 XHR 对象处于“已收到标头”状态(readyState 2)、“正在加载”(readyState 3)状态时,也不是“完成”(readyState 4)。
奇怪的是,如果我在事件处理程序中 alert()
,那么当 readState 为 1、2、3 和 4 时,我确实会看到 onreadystatechange
处理参见http://jsfiddle.net/Rdx6f/1/。与 http://jsfiddle.net/Rdx6f/ 相同的代码,只是 alert()
ing 而不是附加到文档中。
当本机 JavaScript 中的 readyState
为 1、2、3 或 4 时,我还可以检测 onreadystatechange
事件 - 请参阅 http://jsfiddle.net/d7vaH/。 (该代码几乎是逐字摘自《Even Faster Websites》一书第 115 页上 Dylan Schiemann 的 XHR 流实现。)
我是否只是在这里做错了什么,比如错误地使用了 jQuery 的 Ajax 预过滤器或犯了 JavaScript 错误?这可能是 jQuery 中的一个错误吗?
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, however, 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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
仅供参考:我对此进行了深入研究,结果发现 jQuery(自 1.5 起)在内部使用了 onreadystatechange 事件。这样做的结果是 jQuery 将总是将其内部函数写入 onreadystatechange 事件,覆盖您设置的任何内容。每当 AJAX 调用实际发送时,就会发生这种情况,这意味着您为 onreadystatechange 编写的函数将一直工作到那时(这意味着它将一直工作到readyState = 1,但不会更长时间)。
这是目前建议的解决方法: http://jsfiddle.net/tBTW2/
目前,我如果不使用 jQuery(或者回到 1.4.4 或更低版本,它可以完美工作)或编辑 jQuery 代码(因为现在它们总是会覆盖您尝试的任何内容),则无法看到不同(更好)的解决方法钩 在)。
然而,在即将发布的版本中(最有可能在 1.8 中),jQuery 团队计划实现对根据不同的 ReadyState 触发事件的支持。他们会以某种方式使用 Deferreds。
这是保留即将发生的更改的票证:
http://bugs.jquery.com/ticket/9883
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
这是从 jQuery bugzilla bug #8327、
http://jsfiddle.net/d8ckU/1/
Here is the prefiltering done correctly linked from the jQuery bugzilla bug #8327,
http://jsfiddle.net/d8ckU/1/