注入html后,缓存的jQuery选择器会提供与非缓存选择器不同的结果

时间:2013-01-23 11:23:23

标签: javascript jquery caching dom html-injections

找到解决方案!不要打扰创建答案

原来我注入了两次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();
    } );
}

0 个答案:

没有答案