Watch or Monitor Javascript Variables for Change

Execute script if Javascript variable changes

Seven methods for detecting a change to a javascript variable. The options include polling, monioring an object's variable, monitoring an array element, and using a CSS animation event to trigger modification to the DOM, and finally using MutationObserver to notify modification to the DOM. 

The first two examples use polling. Frankly, if you want to monitor a simple variable like x = 1, well sorry but polling is the only way to listen for a change to a simple variable. The remaining 5 examples show how to monitor more complex variables using an objects get and set, and by monitor changes to the DOM itself using CSS animations and MutationObserver. But if you have a simple variable polling is the way to go. I start with the two best ways to use polling.

When polling every half-second (500ms) the difference between the following two functions is literally nothing. SetInterval is timer based so it will fire every 500 ms, while the setTimeout aproach waits 500 ms AFTER the function it has called has completed. In the case of these two examples it just doesn't matter, they work equally well.

Example 1 - polling by setInterval

Set the variable, call the function to monitor the variable, then test by pasting a new value into the console.

  1. value = 1; // paste this into the console to initialize the variable
  2. check1(); // start monitoring the variable
  3. value = 2; // change the variable

The console responds with "check1 value changed from 1 to 2".

<script>
function check1(oldvalue) {
    undefined === oldvalue && (oldvalue = value);
    clearcheck = setInterval(repeatcheck,500,oldvalue);
    function repeatcheck(oldvalue) {
        if (value !== oldvalue) {
            // do something
            clearInterval(clearcheck);
            console.log("check1 value changed from " +
                oldvalue + " to " + value);
        }
    }
}
</script>

Example 2 - polling by setTimeout

Set the variable, then call the functin to start monitoring it. To test it paste the following lines into the console.

  1. value = 1; // paste this into the console to initialize the variable<br>
  2. check2(); // start monitoring the variable<br>
  3. value = 2; // change the variable

The console responds with "check2 value changed from 1 to 2".

<script>

function check1(oldvalue) {
    undefined === oldvalue && (oldvalue = value);
    clearcheck = setInterval(repeatcheck,500,oldvalue);
    function repeatcheck(oldvalue) {
        if (value !== oldvalue) {
            // do something
            clearInterval(clearcheck)
            console.log("check1 value changed from " +
                oldvalue + " to " + value);
        }
    }
}
</script>

Example 3 - monitor an object's variable for change

This method uses an empty object.

There are a couple disadvantages.
- You are limited to using the object's variable (in other words you cannot monitor ANY variable, only variables contained in the object.
- It sends a notification on initialization - something you may not want.

Set the variable, then call the functin to start monitoring it. To test it paste the following lines into the console.

  1. check3.watch = 1; // paste this into the console. "watch" can be any identifer you like
  2. check3.watch = 2; // change the variable

The console responds with "check3 value changed from 1 to 2".

<script>
check3 = new Proxy({}, {
    set: function(target, property, value) {
        // do something
        console.log("check3 value changed from
        " + target[property] + " to " + value);
        target[property] = value;
    }
});
</script>

Example 4 - a function which creates a named object whose variable can be monitored for change

This has the advantages of the method above, and does not send a notification on ititialization. This is because it is initialized before it is checked.

  1. check4 = watch(1); // paste this into the console.
  2. check4.watch = 2; // change the variable

The console responds with "check4 value changed from 1 to 2".

<script>
function watch(j) {
    return new Proxy(JSON.parse ('{"watch":' + j + '}'), {
        set: function(target, property, value) {
            // do something
            console.log("check4 value changed from "
            + target[property] + " to " + value);
            target[property] = value;
        }
    });
}
</script>

Example 5 - the object is an array

This method may be advantageous if you need to iterate through the array for some reason, and if some values are changed this function is automatically called.

  1. check5[0]; // paste this into the console. "check5" can be any identifer you like.
  2. check5[0] = 2; // change the variable, or
    check5["namedKey"] = "hello"; // (key can be named)

The console responds with "check5 value changed from 1 to 2".

<script>
var check5 = new Proxy([], {
    set: function(target, property, value) {
        // do something
        console.log("check5 value changed from "
        + target[property] + " to " + value);
        target[property] = value;
    }
});
</script>

Example 6 - Set up an event listener for DOMSubtreeModified

This method involves setting the value of a DIV and monitoring it for change. Your Javascript would have a getter and setter method to set the value of the DIVs innerHTML. This method monitors the innerHTML of the hidden DIV. for change. The getter and setter functions are not shown in the example, just use the console to set the value.

  1. document.getElementById('watchdiv').innerHTML = 1; // paste this into the console.

The console responds with "check6 value changed to 1"

Set up the DIV in your HTML
<div id="watchdiv" style='visibility:hidden;width:0;height:0'>0</div>

<script>
document.getElementById('watchdiv')
    .addEventListener('DOMSubtreeModified', function() {
    // do something
    console.log("check6 value changed to "
    + document.getElementById('watchdiv').innerHTML);
});
</script>

Example 7 - use MutationObserver

MutationObserver monitors changes to the DOM. MutationObserver can be used in a similar manner as above.

  1. document.getElementById('watchdiv').innerHTML = 1; // paste this into the console.

The console responds with "check7 value changed to 1"

Set up the DIV in your HTML
<div id="watchdiv" style='visibility:hidden;width:0;height:0'>0</div>

<script>
var element = document.getElementById('watchdiv');
element.addEventListener('DOMSubtreeModified', function () {
    element = document.getElementById('watchdiv');
    var MutationObserver = window.MutationObserver
        || window.WebKitMutationObserver
        || window.MozMutationObserver;
    var observer = new MutationObserver(function() {
        // do something
        console.log("check7 value changed to "
        + element.innerHTML);
    });
    observer.observe(element, {childList: true;});
});
</script>

Summary.

All browsers have deprecated the watch method. As a result there is no way to directly monitor a Javascript variable using a native Javascript method. These seven example are basically hacks giving options to use for your particular case should you need to monitor a Javascript variable for change in value. In my opinion the best way to do this is using either of the first two examples, polling by setInterval() or setTimeout().