I've been trying to detect if a spans content has changed and if it has changed to get the value, I've made a code snippet below that will change the span content for testing yet for some reason I can't detect whether the content has changed. I think it's possibly a limitation of the "changed" jquery where you possibly have to declare the change it can expect for it to do anything.
Does anyone have any recommendations of a better way to execute this? Once I have the changed value in js I'll need to do js math on it to finish the solution.
$(document).ready(function() {
// change contents of a span - testing purposes
var delay = (function() {
var timer = 0;
return function(callback, ms) {
clearTimeout(timer);
timer = setTimeout(callback, ms);
};
})();
delay(function() {
document.getElementById('price').innerHTML = '$100.00';
}, 5000);
// detect a change to contents a span
$(".price").change(function() {
alert(this.value);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<span >$90.00</span>
CodePudding user response:
Many issues
- Spans do not have values
- you have a class, not an ID so the selector is
.price
in a jQuery statement or document.querySelector(".price") or document.querySelectorAll(".price") in DOM - Only form elements like
<input>
,<textarea>
and<select>
elements have a change event - What changes the span? Why can't you just add code to where you change the span?
- If not, then you need a mutation observer:
$(function() {
// change contents of a span - testing purposes
const delay = (() => { let timer = 0; return (callback, ms) => { clearTimeout(timer); timer = setTimeout(callback, ms); }; })();
delay(() => { $('.price').html('$100.00'); }, 2000);
// detect a change to contents a span
const elementToObserve = $('.price')[0]; // get the DOM element
const process = () => { // callback
const text = elementToObserve.textContent ; // gets $100.00
const amount = text.trim().slice(1); // converts to 100
console.log("changed to", amount)
}
// create a new instance of 'MutationObserver' named 'observer',
// passing it a callback function
const observer = new MutationObserver(process);
// call 'observe' on that MutationObserver instance,
// passing it the element to observe, and the options object
observer.observe(elementToObserve, { childList: true });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<span >$90.00</span>
Older version 'DOMSubtreeModified' - note it triggers twice!
$(function() {
// change contents of a span - testing purposes
const delay = (() => { let timer = 0; return (callback, ms) => { clearTimeout(timer); timer = setTimeout(callback, ms); }; })();
delay(() => { $('.price').html('$100.00'); }, 2000);
// detect a change to contents a span - deprecated but short
$(".price").on("DOMSubtreeModified", function(e) {
const amount = $(this).text().trim().slice(1); // converts to 100
console.log(new Date(),amount)
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<span >$90.00</span>
CodePudding user response:
Use MutationObserver
$(document).ready(function() {
var delay = (function() {
var timer = 0;
return function(callback, ms) {
clearTimeout(timer);
timer = setTimeout(callback, ms);
};
})();
delay(function() {
document.getElementById('price').innerHTML = '$100.00';
}, 5000);
// Select the target node.
var target = document.querySelector('#price')
// Create an observer instance.
var observer = new MutationObserver(function(mutations) {
console.log(target.innerText);
});
// Pass in the target node, as well as the observer options.
observer.observe(target, {
attributes: true,
childList: true,
characterData: true
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<span id="price">$90.00</span>
CodePudding user response:
If you really need to run some code when the span content is changed you can try Mutation observer https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver#example