Jonathan
Jonathan

Reputation: 9151

Iterating over the DOM with JQuery

I'm trying to iterate over a list of DIVs to check if they have children and if so, add the ID of that DIV to an array along with the class of the child. It's ment to save the buildings for a game, if there's a better way to achieve this I'm open to suggestions.

HTML

<div id="grid" class="grid">
    <div id="t1" class="tile"></div>
    <div id="t2" class="tile">
        <img class="Extractor" title="Extractor" src="images/buildings/Extractor.png">
    </div>
    <div id="t3" class="tile"></div>
    <div id="t4" class="tile"></div>
    <div id="t5" class="tile active"></div>
</div>

JS

function saveGame() {
// Format like: "[['t2','Extractor']['t8','Forge']]"
  saveData.buildings = $('.tile').children().stuff(?);

  localStorage.saveData = JSON.stringify(saveData);
}

Fiddle

Upvotes: 0

Views: 90

Answers (3)

user2437417
user2437417

Reputation:

The .map() method is used to build a new Array. Here we're selecting the child images, and using map against that collection.

The return values from the .map() callback becomes the members of the new Array. Because jQuery's .map() is... odd... we need to double up the returned Array because any outer Array gets flattened into the resulting Array.

$('.tile').children("img").map(function(i, el) { 
    return [[el.parentNode.id, el.className]]; 
}).toArray();

The reason for the .toArray() at the end is that this version of .map() in jQuery actually returns a jQuery object, which is Array-like, but not an actual Array. So we need to convert it.

Upvotes: 3

jds
jds

Reputation: 8259

I haven't tested it, but something with this logic should work fine:

results = [];

// iterate over every element with class 'tile'
$('.tile').each(function() {

  var $$ = $(this);

  // does this instance of class tile have a child?
  if ($$.children().length > 0) {

     // store data
     var parent = $$.attr('id');
     var child  = $$.children().first().attr('class');
     results.append([parent, child]);

  }
});

Upvotes: 0

Patrick Evans
Patrick Evans

Reputation: 42736

use .each to loop over each tile, and then .each on the children to loop over those, there might be a quicker algorithm someone maybe someone will comment if there is.

saveData.buildings = "[['t2','Extractor']['t8','Forge']]"; 
$('.tile').each(function(){
   var parent = $(this); 
   parent.children().each(function(){
      saveData.buildings.push([parent.id,$(this).attr("class")]); 
   });
});
saveData.resources = 'resources';

Upvotes: 1

Related Questions