原来我注入了两次html - 一次在创建选择器之前,然后,由于一些未完成的重构,第二次时间;从而覆盖DOM的相关部分。缓存的选择器仍然引用旧的DOM部分,因此不会被垃圾收集。当然,更改旧部件对新部件没有影响,通过让jQuery重新进行选择可以清楚地显示出来。
我正在尝试创建一个小部件。在运行其脚本之后,小部件找到具有特定代码标记的(在下面引用为$ rootElem),下载一段html代码并将其注入此div。执行此操作后,它会开始将事件附加到输入元素,构建滑块等ui元素。
AFAIK,在将html注入DOM之后,生成的DOM应该等同于在那里开始使用html。事实证明,jQuery认为不然。具体来说,我首先注入html,第二开始查找和缓存选择器结果。
以下代码块应该是等价的(做同样的事情);将<span>awaiting calculation ...</span>
之类的html更改为<span>1234</span>
之类的内容。并且,瞧,如果我将所有html放入同一个文档(不注入它),他们实际上也在做同样的事情。
缓存选择器结果以供以后检索
var $result = $rootElem.find( "div.result p:nth-of-type(1) span" );
$.subscribe( "/server/calculateLoan/finished", function ( e, firstPayment ) {
$result.text( firstPayment ) );
} );
每次进行选择
$.subscribe( "/server/calculateLoan/finished", function ( e, firstPayment ) {
$rootElem.find( "div.result p:nth-of-type(1) span" ).text( firstPayment ) );
} );
但是,如果我将小部件的html代码移出主文档,并在处理它之前将其注入,则只有非缓存(后者)版本才能工作。实际上第一个似乎工作。如果我在匿名函数中设置了一个断点,我可以看到一个奇怪的事情发生:
> $result.text()
<span>awaiting calculation ...</span>
> $rootElem.find( "div.result p:nth-of-type(1) span" ).text()
<span>awaiting calculation ...</span>
> $result.text("1234") //This is not showing in the browser window!
[<span>1234</span>]
> $result.text() //This is not showing in the browser window!
[<span>1234</span>]
> $($result.selector).text() //What kind of magic is this?!
<span>awaiting calculation ...</span>
> $rootElem.find( "div.result p:nth-of-type(1) span" ).text()
<span>awaiting calculation ...</span>
似乎缓存的jQuery选择器指向另一个DOM元素(其更改未显示),而不是我搜索相同的元素。注入html时会发生 ,而不是在将widget的html复制粘贴到页面中时。有人在乎解释发生了什么吗?
Chrome和Firefox都会发生这种情况。
主页上的html位如下所示:
<div id="widget_calculator"><!-- dynamic fetch --> </div>
小部件的html
<h1>Widget calculator</h1>
<div class="user-inputs">...</div>
<div class="result">
<p><span>awaiting calculation ...</span></p>
</div>
注入html的代码
function fetchHtmlTemplate( templateUrl ) {
// set globals
$ = jQuery;
$rootElem = $( "#widget_calculator" );
$.get( templateUrl, function ( htmlTemplate ) {
$rootElem.html( htmlTemplate );
buildWidget();
} );
}