jQuery之后()似乎有竞争条件

时间:2014-04-24 20:48:46

标签: javascript jquery race-condition jquery-after

我有一个非常奇怪的错误,似乎是一个竞争条件会使width();调用给出不同的结果。

我有jQuery after电话:

this.after(
    "<div class='menuItemContainer'>" +
        "<div class='menuItemTitle'>" +
            $("option:selected", this).text() + "<span class='menuItemDownArrow'>&#9660;</span>" +
        "</div>" +
        "<div class='menuItemList'>" +
        selectionMarkup +
        "</div>" +
    "</div>"
);

我在其中将html插入DOM。

接下来,我需要知道元素与类menuItemColums的组合宽度,并使其父div成为宽度。

此标记存在于变量selectionMarkup中。

为此,我执行以下操作:

var w = 0;
$(".menuItemColumn").each(function(){
    w += $(this).width();
    console.log($(this));
    console.log(w);
});
$(".menuItemList").css({
    width: w}
);

这大约在70%的时间内完全符合预期,但有时我会对某些元素采取错误的措施,或者至少肯定第一个元素有时是错误的。

奇怪的部分是对象看起来是正确的,它的属性是正确的宽度,但分配给widht()的给定w是不正确的:

enter image description here

该图片,只是为了澄清,显示了记录w$(this)的结果应该是相同的,因为$(this)的宽度属性似乎是正确的之一。

我一直在调试,发现有两件事情可以让人相信这是竞争条件:

如果我执行最后一段代码,我再次发布给你,当错误再现时,它解决了问题。

如果我执行以下调用,则会给出不同的结果,一个不正确,另一个(第二个)正确:

console.log($(".menuItemColumn:first").width());
setTimeout(function(){console.log($(".menuItemColumn:first").width());},3000);

我的印象是代码的第二部分在第一部分完成之前不会执行,这给出了什么?

注意:我并非100%确定竞争条件是我正在寻找的词,但仍然是这个想法。


更新

作为@ WereWolf-TheAlpha,控制台的输出看起来不像jquery对象,我现在无法再现它,我只能得到这个:

enter image description here

不改变任何代码。

1 个答案:

答案 0 :(得分:1)

这里的问题是,当检查器中的对象折叠时,Chrome检查器将为对象提供引用。单击该箭头以展开对象时,其属性将变为真实。你可以运行它来看它发生:

var obj = {};
for (i=0; i<100; i++)
  obj['foo'+i] = i;
console.log(obj);
for (i=0; i<100; i++)
  obj['foo'+i] = 'gotcha';
console.log(obj);

现在,展开检查器中的第一个对象。疑难杂症!