Kulingar
Kulingar

Reputation: 961

JavaScript, Jquery child node iteration

Though I see lots of posts about this overall topic (best way to get child nodes) I can't find anything regarding iteration and assignment in two-layer nested children. I have seen examples online of children being called with []'s and ()'s. Thanks in advance.

Let's assume I have this HTML and want a string of all the file names (excluding URL path or file extension) inside of the "sortable" UL element.

<ul id="sortable" class="ui-sortable">
    <li class="ui-state-default">
        <img id="aImg" alt="sortable image" src="images/a.jpg" />
    </li>
    <li class="ui-state-default">
        <img id="bImg" alt="sortable image" src="images/b.jpg" />
    </li>
    <li class="ui-state-default">
        <img id="cImg" alt="sortable image" src="images/c.jpg" />
    </li>
</ul>

My JavaScript looks like this:

 var theImageOrder = "";
 var theCounter = 0;
 while (theCounter < $('#sortable').children().length) 
 {
    var theImageName = $('#sortable').children(theCounter).children(0).attr("src").toString().substring($('#sortable').children(theCounter).children(0).attr("src").toString().lastIndexOf("/") + 1, $('#sortable').children(theCounter).children(0).attr("src").toString().lastIndexOf("."));
    theImageOrder = theImageOrder + theImageName;
    theCounter++;
}

I would expect the output would be abc but instead I'm getting aaa.

Upvotes: 0

Views: 1014

Answers (4)

Ron
Ron

Reputation: 201

I put together a vanilla JS recursive example in ES6 that may help future onlookers:

let images = [];

const processChildrenNodes = (node, getNodeChildren) => {
  const nodeChildren = [...node.childNodes];

  for (const thisNode of nodeChildren) {
    if (getNodeChildren)
      processChildrenNodes(thisNode, true);

    if (thisNode.nodeName === 'IMG') {
      images.push(
        thisNode.getAttribute('src')
        .replace('.jpg', '')
        .split('/')
        .filter(item => item !== 'images')
      );
    }
  }
};

processChildrenNodes(document.getElementById('sortable'), true);

This will allow for you to look through all nodes children for an IMG, and then parse the images into an "images" array. This could be compacted even more using reduce, but I figured this would give you an easy option without Jquery.

The example above was tested on JSFIDDLE

Upvotes: 1

km6zla
km6zla

Reputation: 4907

jQuery each() is most likely the answer you are looking for.

var theImageOrder = "";
$('#sortable > li > img').each(function(index, element){
    theImageOrder += element.attr('src').howeverYouWantToModifyThisString();
});

Upvotes: 1

Ram
Ram

Reputation: 144729

var files = $('#sortable img').map(function(){
     return this.src.split('/').pop();
}).get();

http://jsfiddle.net/uyQXP/

Upvotes: 4

adeneo
adeneo

Reputation: 318342

An UL should have only LI children, and I'm guessing selecting images would be clever, as you're looking for the src attribute. $.map returns everyting in an array, you can choose to join it to get a string. Using > makes sure it's only direct children etc :

var images = $.map($('#sortable > li > img'), function(el,i) {
    return el.src.split('/').pop();
}).join(', ');

FIDDLE

Upvotes: 4

Related Questions