jquery: Find and loop through all spans with certain ID within a div?
I have a list that is numbered for each item (1,2,3,4..). I have a function that removes items but when it removes an item the list numbers are not in order anymore (1,3,4...).
What I am trying to do is find all spans starting with "id_" and get the full ID so can can reset the numbers to the correct order.
$('[id^="ta开发者_如何转开发ble_"]').each(function(index, table){
});
The way I am trying to do it I cannot figure out how to get the ID of the span.
<div id="list">
<div id="list_1">
<table border="0" width="100%" id="table_1">
<tbody>
<tr>
<td>
<span id="id_1">1</span>
</td>
</tr>
</tbody>
</table>
</div>
<div id="list_2">
<table border="0" width="100%" id="table_2">
<tbody>
<tr>
<td>
<span id="id_2">2</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
Thanks
UPDATED
Ok I have taken a bits from each post to get this
var i = 1;
$('span[id^="id_"]', "#list").each(function(index){
var id = this.id;
$('#'+id).html(i+'. ');
i++;
});
Thanks all for you help.
Update I missed that you already had an each
loop. It looks fine except you seem to be looking for id
s starting with "table_", but you don't have any (you have "list_" and "id_"). Also, you're doing it completely unbounded, which will probably be quite a lot of work. The more narrow the selector can be, the better (usually).
The way I am trying to do it I cannot figure out how to get the ID of the span.
Within an each
loop, the id
of the DOM element is available as this.id
.
My original answer addresses how to do this with the markup you quoted.
Original answer:
jQuery has the "attribute starts with" selector, so you can find all the children that are span
s with an id
starting with "id_" and then loop through assigning new IDs to them:
$("#list").find('span[id^="id_"]').each(function(index) {
this.id = "id_" + (index + 1);
});
That uses find
to find them, then each
to loop through them. I assumed there you wanted to start the numbering with 1 rather than with 0, hence adding one to the index
that jQuery passes into each. Assigning the IDs can be done with the raw DOM element (
thisin the
each` callback) as there's nothing complicated about it.
Although actually, you don't need a separate call to find
, you can just use a descendant selector:
$('#list span[id^="id_"]').each(function(index) {
this.id = "id_" + (index + 1);
});
Live example
Further update: If you really want to have fun, you can renumber the lists, the tables within the lists, and the spans within the tables:
$('#list div[id^="list_"]').each(function(listIndex) {
// This is called for each list, we renumber them...
++listIndex; // So it's 1-based
this.id = "list_" + listIndex;
// ...then process the tables within them
$(this).find('table[id^="table_"]').each(function(tblIndex) {
// Called for each table in the list, we renumber them...
++tblIndex; // 1-based
this.id = "table_" + listIndex + "_" + tblIndex;
// ...then process the spans
$(this).find('span[id^="id_"]').each(function(spanIndex) {
// Called for each span in the table
++spanIndex; // 1-based
this.id = "id_" + listIndex + "_" + tblIndex + "_" + spanIndex;
});
});
});
Live example
If a framework-agnostic solution is acceptable, something along the following lines should do the trick:
var myDiv = document.getElementById("targetDivId");
var displayNum = 1;
var nodes = myDiv.getElementsByTagName("span");
for (var index = 0; index < nodes.length; index++) {
var node = nodes[index];
if (node.id.indexOf("id_") == 0) {
node.id = "id_" + displayNum;
node.innerHTML = displayNum;
displayNum++;
}
}
You can use the attributeStartsWith selector.
$('span[id^="id_"]', "#list").each(function(i){ ... });
You could use
$('[id^="table_"]').each(function(index, table){
$('span:first', this).attr('id');
});
Basically this looks for the FIRST span element inside each table. If there would be more spans, you would have to combine both:
$('[id^="table_"]').each(function(index, table){
$('span[id^="id_"]:first', this).attr('id');
});
Not 100% sure if the last one works.
If you are trying to change the ids of each groups list, table and span then you will need to
// for each list
$('[id^="list_"]').each(function(index, table){
// for the inner table and span and the actual list
$('table[id^="table_"], span[id^="id_"]', this).add(this).each(function(){
// split the id to the prefix and number
var id_parts = this.id.split('_');
// assign new id based on existing prefix and the new number
this.id = id_parts[0] + '_' + (index+1);
})
});
if you want to change the text as well then use
// for each list
$('[id^="list_"]').each(function(index, table){
// for the inner table and span and the actual list
$('table[id^="table_"], span[id^="id_"]', this).add(this).each(function(){
// split the id to the prefix and number
var id_parts = this.id.split('_');
// assign new id based on existing prefix and the new number
this.id = id_parts[0] + '_' + (index+1);
// single out the span and change its text
}).filter('span').text(index+1);
});
精彩评论