为什么jQuery的$()。each()函数似乎正在失去对DOM的追踪?

时间:2009-10-08 17:19:58

标签: jquery dom

我最近开始遇到一个非常奇怪的问题。说实话,除了展示它之外,我不完全确定如何描述它。

以下是相关的HTML:

<div class="component container w100 noEdit" id="contentWrapper"> 
<div class="component container w50" id="container1"> 
   <div class="component text w50" id="text1"> 
      Text1 
   </div> 
</div> 
<div class="component container w25" id="container2"> 
   Container2 
</div> 
<div class="component container w25" id="container3"> 
   Container3 
</div> 
<div class="component container w25" id="container4"> 
   Container4 
</div> 
</div> 

以及相关的JavaScript:

$(document).ready(function () { 
   //Add the Grab Bar to container components on the page. 
   $('.component').each(wrapComponentForEdit); 
   $('#contentWrapper').sortable(); 
   $('#contentWrapper').disableSelection(); 
}); 

var wrapComponentForEdit = function() 
{ 
   if (!$(this).hasClass('noEdit')) { 
      $(this).html('<div class="componentBorder">' + $(this).html() + '</div>'); 
      $(this).prepend('<div class="grabBar_l"><div class="grabBar_r"><div class="grabBar"></div></div></div>'); 
      alert($(this).attr('id')); 
   } 
} 

这样做的最终结果是我看到了为container1,text1,container2,container3,容器4弹出一个警告。但是只有容器(不是文本)最终得到了$()的视觉变化。应该做每个()。

任何人都知道到底发生了什么事?

谢谢!

编辑 - 一种不同的方式,仍然失败

我尝试了这个,结果相同:

$(document).ready(function () {
    //Add the Grab Bar to container components on the page.
    var matched = $('.component');
    var componentCount = $(matched).size();
    for (i = 0; i < componentCount; i++)
    {
        wrapComponentForEdit($(matched).eq(i));
    }
    $('#contentWrapper').sortable({ handle: '.grabBarBit', tolerance: 'pointer'});
    $('#contentWrapper').disableSelection();
});

var wrapComponentForEdit = function(component)
{
    if (!$(component).hasClass('noEdit')) {
        $(component).html('<div class="grabBar_l grabBarBit"><div class="grabBar_r grabBarBit"><div class="grabBar grabBarBit"></div></div></div><div class="componentBorder">' + $(component).html() + '</div>');
        alert($(component).attr('id'));
    }
}

编辑2:另一种替代方法,但这个方法有效

我尝试了另一种做事方式,这种方式有效。但是,最初的问题仍然存在。从这种新方法如何运作来判断,在我看来DOM正在更新,但jQuery没有用它进行更新,所以它失去了对子元素的跟踪。

$(document).ready(function () {
    //Add the Grab Bar to container components on the page.
    var componentCount = $('.component').size();
    for (i = 0; i < componentCount; i++)
    {
        wrapComponentForEdit($('.component').eq(i));
    }
    $('#contentWrapper').sortable({ handle: '.grabBarBit', tolerance: 'pointer'});
    $('#contentWrapper').disableSelection();
});

var wrapComponentForEdit = function(component)
{
    if (!$(component).hasClass('noEdit')) {
        $(component).html('<div class="grabBar_l grabBarBit"><div class="grabBar_r grabBarBit"><div class="grabBar grabBarBit"></div></div></div><div class="componentBorder">' + $(component).html() + '</div>');
        alert($(component).attr('id'));
    }
}

1 个答案:

答案 0 :(得分:0)

这让我想起了另一个问题

wait until previous .append() is complete (jquery)

当为下一个(嵌套的)html标记再次调用该函数时,也许.html或.prepend命令仍在运行。

当您删除外部组件类时,查看问题是否消失:

<div class="container w50" id="container1"> 
   <div class="component text w50" id="text1"> 
      Text1 
   </div> 
</div>

如果这确实消除了您的问题,您将需要一种更慢的方式来更新等待上一次更改完成之前的html。

有关附加的更多信息,请参阅43,439 reasons to use append() correctly(其中一些好主意)