2012-05-26 62 views
2

我只是测试用另一个页面替换整个页面使用JavaScript和I found this answerdocument.write。至于为什么document.write,我需要用同一页面替换整个HTML,包括脚本和样式。document.write和委托事件处理程序持久性

它做我想要的,但我似乎无法与我的事件处理程序保持一致。

$(document).delegate(...); 

目前,我有怪异的结果:我的处理程序使用所有连接到documentIn a fiddle I made,它附加一个处理程序。点击后,事件触发,重写页面,再次运行该函数 - 但它不附加处理程序。

但是在我的项目中,我正在执行相同的例程(d.w(),然后添加处理程序)。它重新连接一次,处理程序工作,但在完成第二个例程(仍在同一页面上)之后,它不再连接。

所以我的问题是:

  • 当使用d.w(),执行现有的处理程序得到从document删除?
  • window以及document以后相同d.w() s?或者它们以某种方式“更新”
  • 已经解析的脚本是否保留在内存中并在后续的d.w()之后运行?或者它们也被擦除?
+1

'的$(document).find( “跨度”)''返回在1'时'patch'运行这两种情况下,但不知何故'.delegate'不工作的第二次。 – pimvdb

回答

6

(以下适用于谷歌浏览器)

只有document被清除,在内存中的脚本仍保持不变。您可以通过将某些内容设置为变量并通过.open清除文档后查看它是否存在来轻松进行测试。

旧的本机处理程序因此从文档中丢失,但jQuery仍然认为该处理程序存在于其自己的事件模型中。您可以通过编辑日志,看看它:

console.log('patch', JSON.stringify($.cache)); 

jQuery的永远只重视每个事件的单个原生处理器,所以如果你有document注册"click"事件,连接使用jQuery进一步处理不重视新本地处理程序,而是将处理程序推入jQuery内部处理程序数组中。

现在,因为document.open删除本机的处理程序,但没有明确的JavaScript,jQuery的仍然认为原生处理器存在,并进一步.delegate只到jQuery的内部处理器阵列。如果你用简单的旧document.onclick替换你的处理程序,你会看到它开始工作。

您还可以,如果你添加$(document).unbind()继续使用jQuery(或更稳健$.cache = {};,但这是内部的,如有更改)的.delegate之前,让jQuery的再次同步。否则它不会,因为它不知道你叫document.open

所以:

  1. 他们仍然是相同的对象,可以通过保存参考,并检查安剑铮,卓杰document.open
  2. 他们留在记忆测试。

http://jsfiddle.net/wphzt/4/

+0

+1,感谢您的信息发布。我做了一些调试 - 相关的代码似乎是[这里](https://github.com/jquery/jquery/blob/master/src/event.js#L109)。队列仍然在jQuery的内存中,所以它不会再次调用addEventListener,但实际上处理程序*已被删除,因为文档已被清除。结果,进一步的点击根本不被注册。 – pimvdb

+0

啊,我明白了。所以jQuery仍然认为它是由于它自己的记录而存在的。这解释了很多。谢谢! – Joseph

+0

有趣的是,如果我在分配处理程序之前从'jQuery.cache'中删除'document'条目...'var cache_idx = document [$。expando]; if($ .cache [cache_idx]){delete $ .cache [cache_idx]; }'......下一次尝试调用处理程序会导致Firefox中出现错误'尝试在已清除的范围上运行编译并运行脚本@ jquery.min.js:3'不知道这意味着什么。 http://jsfiddle.net/wphzt/5/ – 2012-05-26 14:33:04

0

它停止从第二次工作的唯一原因是起因为你的函数你写

document.write('<span>'+(++i)+'</span>'); 

在这种情况下,下一次的文档没有委托函数递增跨度值,但只有你在上面突出显示的代码段中写的内容。因此,如你所怀疑的那样,是的,它们也会被擦除。希望这可以帮助。

相关问题