DOM元素的行为不符合预期

DOM elements not behaving as expected.

本文关键字:不符合 元素 DOM      更新时间:2024-03-02

我似乎完全无法解决这个问题。当我运行这个循环时:

for ( var i=0; i < 10; i++ ) {
    var $items = $(balls()); 
    console.log($items);
    $container.imagesLoaded(function(){
        $container.append( $items ).masonry( 'appended', $items, true );
    });
}

第一项和最后一项都很好,它们看起来像:

<div class="box masonry-brick" id="resultBox" style="top: 0px; position: absolute; left: 0px; "><div><p>NAME</p><img src="pathtoimage.jpg"><boxbottom id="boxBottom">NUM%</boxbottom></div></div>

但其他8个都不好,它们看起来像:

<div class="box" id="resultBox""><div><p>NAME</p><img src="pathtoimage.jpg"><boxbottom id="boxBottom">NUM%</boxbottom></div></div>

因此,没有应用"砖石"类别,这意味着它们不会被砖石加工。

同样相关的还有:

function balls(){
    var boxes = [];
    $iterator -= 1;
    var box = document.createElement('div'),
        spacerdiv = document.createElement('div'),
        para = document.createElement('p'),
        img = document.createElement('img'),
        boxBottom = document.createElement('boxBottom'),
        name = document.createTextNode( $test[$iterator][1][2]['name'] ),
        percentage = document.createTextNode(Math.floor($test[$iterator][0]*100)+'%');
    box.className = 'box';
    box.id = 'resultBox';
    img.src= 'scripts/php/timthumb.php?src='+$test[$iterator][2]+'&q=100&w=300';
    boxBottom.id='boxBottom';
    box.appendChild( spacerdiv );
    spacerdiv.appendChild( para);
    para.appendChild(name);
    spacerdiv.appendChild( img );
    spacerdiv.appendChild(boxBottom);
    boxBottom.appendChild(percentage);
    // add box DOM node to array of new elements
    return box;
}

我认为这里的DOM模型有些奇怪,也许是因为元素是动态创建的
我已经做了一整天了,我都快累坏了。。。

我假设每次调用.imagesLoaded()都会绑定回调函数,以便稍后在实际加载图像后异步运行。如果是这样的话,你可以把你的代码改成这样:

for ( var i=0; i < 10; i++ ) {
   (function() {
       var $items = $(balls()); 
       console.log($items);
       $container.imagesLoaded(function(){
           $container.append( $items ).masonry( 'appended', $items, true );
       });
   })();
}

因为JS没有块作用域,所以它只有函数作用域。因此,即使您将var语句放置在循环中,您的$items变量的范围实际上并不局限于循环,并且当执行使用.imagesLoaded()设置的回调时,它们都引用了相同的$items-它将保持循环结束时的值。通过将代码封装在一个函数中(在本例中是一个立即执行的匿名函数表达式,请注意末尾的()),将为循环的每次迭代创建一个新的$items变量,因此每个.imagesLoaded()回调都引用正确的$items

更高效的版本(因为它不会在每次迭代中创建新函数):

function addBalls() {
   var $items = $(balls()); 
   console.log($items);
   $container.imagesLoaded(function(){
       $container.append( $items ).masonry( 'appended', $items, true );
   });
}
for ( var i=0; i < 10; i++ )
    addBalls();

无论哪种方式,如果您确实需要在循环中引用循环索引i,您只需将其作为参数传递给函数即可。

这里很可能发生了一些奇怪的事情:

boxBottom = document.createElement('boxBottom'), 

createElement的参数应该是有效的标记名称。