user3436467 user3436467 - 27 days ago 7
jQuery Question

dynamically detect change to span element

I have span elements that are dynamically generated from an ajax response. I am trying to detect a change to the span value using the below code and it seems to work in jsfiddle with fixed elements but not in a real scenario where data is dynamically generated. The span values are updated with setInterval function number increment which i am trying to detect.

The steps i am taking are - would appreciate some advice on why my code would not be working?


  1. For all elements with an id containing "minutes" <- these will be my span elements

  2. Get the id's

  3. Detect any change in all elements with id's from step 2

  4. When change detected, get the span element value

  5. Check if span value is greater than 00 i.e. 01 (this is actually a minute value)

  6. If condition from step 5 is met then apply css

  7. If condition from step 5 is not met then remove css



$('[id*="minutes"]').each(function() {
spanid = $(this).attr('id');

console.log(spanid);

$("#"+spanid).on('change',function(){

spanval = $(this).text();
id = $(this).attr('id').charAt(0);

if(spanval > 00) {
$('#results').text(span);

$("#"+id+"-wt-html").css({"background":"#FFE95B", "color":"red"});
} else {
$("#"+id+"-wt-html").removeAttr("style")
}
});
});


sample HTML



<td id="9-wt-html">
<div id="9-wt-ajax">
<span id="9-hours">00</span>:
<span id="9-minutes">15</span>:
<span id="9-seconds">12</span>
</div>
</td>


The above span elements are created before the ajax call using a fixed script below:

for (var key in skills_arr) {
//console.log(skills_arr[key]+" - "+key);
$('#Table > tbody:last-child').append('<tr><td>'+skills_arr[key]+'</td><td id="'+key+'-cw-html"><div id="'+key+'-cw-ajax"></div></td><td id="'+key+'-aa-html"><div id="'+key+'-aa-ajax"></div></td><td id="'+key+'-wt-html"><div id="'+key+'-wt-ajax"><span id="'+key+'-hours">00</span>:<span id="'+key+'-minutes">00</span>:<span id="'+key+'-seconds">00</span></div></td><td id="'+key+'-op-html"><div id="'+key+'-op-ajax"></div></td></tr>');
}

Answer

Okay, I have created a snippet below based on my understandings.

Also, would like to highlight the below points.

For span element, we can't listen for the change event. Instead, the code below will listen for the DOMSubtreeModified event.

Also, we can directly listen for the event of the element using $('[id*="minutes"]').on('DOMSubtreeModified', function(){}) if the element exists before this line.

Otherwise, we have to listen the same from its parent or document as given below.

$('#Table').on('DOMSubtreeModified', '[id*="minutes"]', function() {
    var span = $(this);
    var spanValue = parseInt(span.text());
    var id = span.attr('id').charAt(0);
    if(spanValue > 0) {
            //$('#results').text(span); // Not sure what is this?

            $("#"+id+"-wt-html").css({"background":"#FFE95B", "color":"red"});
    } else {
            $("#"+id+"-wt-html").removeAttr("style")
    }
});

var skills_arr = {
  '9': 'some value here'
};

for (var key in skills_arr) {
$('#Table > tbody:last-child').append('<tr><td>'+skills_arr[key]+'</td><td id="'+key+'-cw-html"><div id="'+key+'-cw-ajax"></div></td><td id="'+key+'-aa-html"><div id="'+key+'-aa-ajax"></div></td><td id="'+key+'-wt-html"><div id="'+key+'-wt-ajax"><span id="'+key+'-hours">00</span>:<span id="'+key+'-minutes">00</span>:<span id="'+key+'-seconds">00</span></div></td><td id="'+key+'-op-html"><div id="'+key+'-op-ajax"></div></td></tr>');
}

setTimeout(function(){
  $('#9-minutes').text('15');
  $('#9-seconds').text('12');
}, 3000);

setTimeout(function(){
  $('#9-minutes').text('00');
  $('#9-seconds').text('10');
}, 6000);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="Table">
  <tbody>
  </tbody>
</table>
<p>Results:</p>
<div id="#results">
</div>