2013-03-04 13 views
5

Sto collegando un array e modificando il contenuto dell'array, ma non ottengo i risultati che mi aspetto. Cosa mi sto perdendo o sto sbagliando?Sto collegando un array e modificando il contenuto dell'array, ma non ottengo i risultati che mi aspetto.

Ho due gruppi di div (uno con attacco di classe e un altro nemico) con tre elementi ciascuno. Sto provando a selezionare un elemento da ciascun lato creando un bordo attorno ad esso. Ora voglio passare le classi da un attaccante al nemico e viceversa. Ma quando uso il ciclo, in qualche modo ignora alcuni elementi e cambia solo una o due classi div. Qui è il mio codice:

HTML:

<div id="army1"> 
    <div class="attacker"> 
     <img src="img/Man/Archer.jpg" /> 
     <div class="hp"></div> 
    </div> 
    <br><div class="attacker"> 
     <img src="img/Man/Knight.jpg" /> 
     <div class="hp"></div> 
    </div> 
    <br><div class="attacker"> 
     <img src="img/Man/Soldier.jpg" /> 
     <div class="hp"></div> 
    </div> 
    <br>    
</div> 

<div id="army2"> 
    <div class="enemy"> 
     <img src="img/Orcs/Crossbowman.jpg" /> 
     <div class="hp"></div> 
    </div> 
    <br><div class="enemy"> 
     <img src="img/Orcs/Mine.jpg" /> 
     <div class="hp"></div> 
    </div> 
    <br><div class="enemy"> 
     <img src="img/Orcs/Pikeman.jpg" /> 
     <div class="hp"></div> 
    </div> 
    <br>    
</div> 

E il mio codice javascript:

var attacker = document.getElementsByClassName('attacker'); 
var enemy = document.getElementsByClassName('enemy'); 


var button = document.getElementById("fight"); 

// var class1 = document.getElementsByClassName("first")[0].getAttribute("class"); 
// class1 = class1.split(" "); 

//choose attacker 
for (var i = 0; i < attacker.length; i++) { 
    attacker[i].onclick = function() { 
     //select only one attacker and set its id to attackerid 
     if (this.getAttribute('class') != 'attacker first') { 
      resetAttackerClasses(); 
      this.setAttribute('class', 'attacker first'); 
     } else { 
      resetAttackerClasses(); 
     } 

    }; 
} 

//choose enemy 
for (var i = 0; i < enemy.length; i++) { 
    enemy[i].onclick = function() { 
     //select only one attacker and set its id to enemyid 
     if (this.getAttribute('class') != 'enemy second') { 
      resetEnemyClasses(); 
      this.setAttribute('class', 'enemy second'); 
     } else { 
      resetEnemyClasses(); 
     } 
    }; 
} 

//fight 
button.onclick = function() { 
    //take off enemy health 
    document.getElementsByClassName('enemy second')[0].children[1].style.width = '50px'; 

    resetAttackerClasses(); 
    resetEnemyClasses(); 

    for (var i = 0; i < attacker.length; i++) { 
      attacker[i].setAttribute('class', 'enemy'); 
      enemy[i].setAttribute('class', 'attacker'); 
    }; 
}; 


function resetAttackerClasses() { 
    for (var i = 0; i < attacker.length; i++) { 
     attacker[i].setAttribute('class', 'attacker'); 
    }; 
} 
function resetEnemyClasses() { 
    for (var i = 0; i < attacker.length; i++) { 
     enemy[i].setAttribute('class', 'enemy'); 
    }; 
} 

risposta

8

È perché si sta rimuovendo la classe che è stato utilizzato per andare a prendere l'elemento, il che significa che l'elemento verrà automaticamente rimosso dal NodeList dal vivo (poiché non corrisponde più alla query).

Quando ciò accade, la NodeList viene reindicizzata, quindi l'elemento successivo diventa quello corrente e si finisce saltandoci sopra con il prossimo i++;

Per risolvere il problema, iterare al contrario.

Se non si desidera tornare indietro, quindi decrementare l'indice ogni volta che si rimuove un elemento dall'elenco.

+1

Dovresti essere in grado di copiarlo e quindi scorrere il nuovo array: var nodeArr = Array.prototype.slice.call (theNodeList, 0); – lmortenson

+0

@lmortenson: Sì, funzionerà anche tu. Bello per evitare la copia però. Se OP si preoccupa per l'ordine, preferisco diminuire l'indice. –

Problemi correlati