2013-04-14 8 views
5

Sono molto confuso sul motivo per cui solo l'ultimo elemento viene inserito quando tento di aggiungere più elementi all'interno di un ciclo for.Come inserire più elementi in un elemento tramite append in un ciclo for?

Ho creato uno JsFiddle che mostra la mia impossibilità di farlo funzionare. Mi aspetto di inserire 100 tag di ancoraggio, ma è inserito solo l'ultimo elemento.


Per l'amor del posteriore, ecco il relativo JavaScript, il TODO segna la parte rilevante:

Math.randomNumber = function(max) { 
    return Math.round(Math.random() * max % max); 
} 


var Door = { 
    $el: $('<a>', { 
     class: 'door selectable' 
    }), 
    number: null, 
    isSelected: false, 
    containsZonk: true, 
    bind: function() { 
     var that = this; 
     this.$el.on('click tap', function() { 
      that.isSelected = true 
     }); 
    } 
} 

var Platform = { 
    $el: null, 
    doorCount: null, 
    jackpotNumber: null, 
    doors: [], 
    init: function($el, doorCount) { 
     this.$el = $el; 
     this.doorCount = doorCount; 

     for (var i = 0; i <= doorCount - 1; i++) { 
      var door = Object.create(Door); 
      door.number = i; 
      door.$el.html(i.toString()); 
      this.doors.push(door); 

      /* TODO: wtf why is only last one inserted? */ 
      this.$el.append(door.$el); 
     } 

     this.jackpotNumber = Math.randomNumber(doorCount); 
     this.doors[this.jackpotNumber].containsZonk = false; 
    } 
} 
    $(document).ready(function(){ 
     var platform = Object.create(Platform); 
     var $game = $('.door_game'); 
     platform.init($game, 100); 
    }); 

voglio inserire tutti i 100 elementi in div.door_game:

<body> 
    <h1>Zonk!</h1> 
     <div class="door_game" data-doors="10"> 
     </div> 
</body> 
+1

probabilmente è necessario modificare 'Math.round (Math.random() * 100% 100)' a 'Math.round (Math.random() * max% max)' – razzak

+0

@razzak Sì, ho notato anche questo mentre preparavo la domanda, non era necessario risolvere il problema reale. Grazie per avermelo fatto notare comunque. – k0pernikus

+1

anche questo non ha senso 'this.doors [this.jackpotNumber] .containsZonk = true;' quando tutti gli oggetti 'door' hanno questa proprietà' containsZonk: true, '! potresti voler cambiarlo in 'cotainsZonk: false,'? – razzak

risposta

6

È perché tutta la vostra le porte condividono lo stesso $el.

http://jsfiddle.net/U9swZ/9/

var Door = { 
    number: null, 
    isSelected: false, 
    containsZonk: true, 
    bind: function() { 
     var that = this; 
     this.$el.on('click tap', function() { 
      that.isSelected = true 
     }); 
    }, 
    init: function() { 
     this.$el = $('<a>', { 
      class: 'door selectable' 
     }); 
     return this; 
    } 
} 
2

La Porta $ el viene creato una volta e che è per questo che viene aggiunto e aggiunto di nuovo (cioè spostato ancora e ancora) in modo che si vede solo l'ultimo. @plalx ha ragione al riguardo.

Morever, qualcosa di molto importante dal momento che si aggiunge centinaia di porte, utilizzare un frammento di documento (var frag = document.createDocumentFragment()) prima del ciclo, per raccogliere voi porte (frag.appendChild(...)) e aggiungere questo frammento di documento alla Piattaforma $ el dopo il ciclo (this.$el.appendChild(frag)). Il guadagno in termini di prestazioni è molto importante con una tale quantità di elementi.

E, non esitate a clonare un elemento invece di ricostruirlo. È molto più veloce. È anche possibile utilizzare il metodo DOM API cloneNode(false) per eseguire una copia non approfondita dell'elemento originale.

+0

Il mio obiettivo non era la prestazione quando rispondevo, ma è sicuramente una buona pratica. È bello che tu me ne abbia parlato. +1 – plalx

+0

Non voglio essere eccessivamente pungente, ma questo è più un commento che una risposta alla domanda. Valuto l'intuizione, quindi ti darò +1 comunque. – k0pernikus

+0

Mi sono preso la libertà di aggiungere un esempio e confrontato i tempi. Grazie per avermi insegnato il concetto :) – k0pernikus