In the process of learning some JavaScript, I've managed to assemble examples that help me periodically (every 3 seconds, in this example) refresh the content of my web page, and take a specific action (refresh the page) after one of the dynamic tags is populated with a specific string.
What I cannot seem to figure out is how to stop the dynamic content from being polled once a tag () I'm evaluating matches a specific condition.
Here is what I have in place, which is generally working for me:
Say for example I have a web page that contains dynamic elements assigned the id tags of "leftHealth", "leftEnergy", "rightEnergy", and "turnMsg":
// On page load, instantiate a listener and begin polling the server for content.
window.addEventListener('load', function(){
var xhr = null;
function getXmlHttpRequestObject(){
if(!xhr){
// Create a new XMLHttpRequest object
xhr = new XMLHttpRequest();
}
return xhr;
}
function updateLiveData(){
var now = new Date();
// Date string is appended as a query with live data to avoid caching issues
var url = 'updatedVals.php?ID=' + ID + '&userName=' + userName + '&time=' + now.getTime();
xhr = getXmlHttpRequestObject();
xhr.onreadystatechange = eventHandler;
// asynchronous requests
xhr.open("GET", url, true);
// Send the request over the network
xhr.send(null);
}
updateLiveData();
function eventHandler(){
// Check response is ready or not
if(xhr.readyState == 4 && xhr.status == 200){
let data = JSON.parse(xhr.responseText);
['leftHealth','leftEnergy','rightEnergy','turnMsg'].forEach(function(i){
document.getElementById(i).innerHTML = data[i]
});
setTimeout(updateLiveData, 3000); // Update the live data every 3 sec
}
}
});
And here I watch for one of the tags matching a certain value and, when that happens, wait ~4 seconds then refresh the page:
// Start listening for changes in the root HTML element of the page.
mutationObserver.observe(document.documentElement, {
attributes: true,
characterData: true,
childList: true,
subtree: true,
attributeOldValue: true,
characterDataOldValue: true
});
var counter = 0;
var i = setInterval(function(){
// Evaluate the "turnMsg" document element we're evaluating and check for the string "Stunned".
// But even if it does not show up, refresh the page about every minute or so.
let s = document.getElementById('turnMsg').innerHTML;
let result = s.includes("Stunned");
counter++;
// If <div id="turnMsg"> contains "Stunned", wait 4 seconds then refresh.
if ((result) || (counter == 15)){
if (result){
var i = setInterval(function(){
}, 4000);
}
clearInterval(i);
mutationObserver.disconnect(); // Stop the MutationObserver from listening for changes.
location.reload(); // Reload the page.
}
}, 3000);
This is all working reasonably well (perhaps given how sketchy my JavaScript knowledge is!). But what I cannot quite figure out how to do is STOP the process of polling the server (sending that XmlHttpRequest) every 3 seconds and updating content of the page once one of the content refresh polls pulls back the condition that the value going into is less than zero. When the value returned in document.getElementById('leftHealth').innerHTML < 0, I no longer need the web page's content to refresh -- that's just wasting bandwidth and DB queries in the target php page because values returned from thes server will no longer change.
When your condition to stop matches, call clearInterval()
on the 3-second interval timer.
Then use setTimeout()
to reload the page 4 seconds later.
var counter = 0;
var three_second_timer = setInterval(function() {
// Evaluate the "turnMsg" document element we're evaluating and check for the string "Stunned".
// But even if it does not show up, refresh the page about every minute or so.
let s = document.getElementById('turnMsg').innerHTML;
// If <div id="turnMsg"> contains "Stunned", wait 4 seconds then refresh.
if ( s.includes("Stunned") || (++counter == 15)) {
clearInterval(three_second_timer);
mutationObserver.disconnect(); // Stop the MutationObserver from listening for changes.
setTimeout(function() {
// Reload the page.
location.reload();
}, 4000);
}
}, 3000);