Les éléments du DOM ne se comportent pas comme prévu.
-
11-12-2019 - |
Question
Il me semble complètement incapable de résoudre ce problème.Quand je lance cette boucle :
for ( var i=0; i < 10; i++ ) {
var $items = $(balls());
console.log($items);
$container.imagesLoaded(function(){
$container.append( $items ).masonry( 'appended', $items, true );
});
}
Le premier élément et le dernier élément vont bien, ils ressemblent à :
<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>
Mais les 8 autres ne vont pas bien, ils ressemblent à :
<div class="box" id="resultBox""><div><p>NAME</p><img src="pathtoimage.jpg"><boxbottom id="boxBottom">NUM%</boxbottom></div></div>
Il n'y a donc pas de classe « maçonnerie-brique » appliquée, ce qui signifie qu'elles ne sont pas traitées par la maçonnerie.
Sont également pertinents :
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;
}
Je pense qu'il se passe quelque chose d'étrange avec le modèle DOM ici, peut-être parce que les éléments sont créés dynamiquement ?
J'ai été là toute la journée et je suis épuisé...
La solution
J'assume que chaque invocation de .imagesLoaded()
lie votre fonction de rappel à exécuter plus tard, de manière asynchrone, une fois les images chargées.Si c'est le cas, vous pouvez modifier votre code comme suit :
for ( var i=0; i < 10; i++ ) {
(function() {
var $items = $(balls());
console.log($items);
$container.imagesLoaded(function(){
$container.append( $items ).masonry( 'appended', $items, true );
});
})();
}
... parce que JS n'a pas de portée de bloc, il n'a qu'une portée de fonction.Ainsi, même si vous avez placé le var
instruction à l'intérieur de la boucle, votre $items
la variable n'est pas réellement limitée dans la portée de la boucle et lorsque les rappels sont configurés avec .imagesLoaded()
sont exécutés, ils font tous référence au même $items
- qui contiendra la valeur à la fin de la boucle.En encapsulant votre code dans une fonction (dans ce cas, une expression de fonction anonyme qui est immédiatement exécutée - notez le ()
à la fin) un nouveau $items
La variable est créée pour chaque itération de la boucle et donc chacune de vos .imagesLoaded()
les rappels font référence au bon $items
.
Version plus efficace (car elle ne crée pas de nouvelle fonction à chaque itération) :
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();
Quoi qu'il en soit, si vous avez réellement besoin de référencer l'index de la boucle i
dans la boucle, vous le transmettez simplement en tant que paramètre à la fonction.
Autres conseils
Très probablement quelque chose d'étrange se passe ici:
boxBottom = document.createElement('boxBottom'),
L'argument pour Creeeeeyment doit être un nom de balise valide.