Reputation: 961
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
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
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
Reputation: 144729
var files = $('#sortable img').map(function(){
return this.src.split('/').pop();
}).get();
Upvotes: 4
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(', ');
Upvotes: 4