Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JS to monitor the CSS property change like "display:none"=>"display:block"?

I want to run some JS code when an image's CSS property "display" has been changed by any other JS script/functions. Is there any method to monitor that change and setup a callback function?

$(this).bind.('propertychange', function(){}) 

cannot do this, and setInterval is also a bad idea.

What else could be done?

like image 407
Alix Avatar asked Dec 28 '22 01:12

Alix


2 Answers

This is what you are looking for:

document.documentElement.addEventListener('DOMAttrModified', function(e){
  if (e.attrName === 'style') {
    console.log('prevValue: ' + e.prevValue, 'newValue: ' + e.newValue);
  }
}, false);
like image 145
Marian Zburlea Avatar answered Dec 29 '22 14:12

Marian Zburlea


This is inside the legacy JavaScript files that you do not want to modify:

// this is your original, unmodified function
function originalFunction(sel) {
    alert(sel);
    $(sel).css("display","none");
}

This is in your code:

// here is a sample callback function you pass into the extended function below
function myCallback(s) {
    alert("The image with src = '" + $(s).attr("src") + "' has been modified!");
}


// here is how you can extend the function to do what you want 
  // without needing to modify the actual code above
originalFunction = (function(legacyFn, callback) {

    // 1 arg function to be returned and reassigned to originalFunction
    return function(sel) {

        // call "original" originalFunction, with alert and image hide.
        legacyFn(sel);  

        if(callback) callback(sel);  // invoke your callback
    }

})(originalFunction, myCallback);

The variable originalFunction is assigned a function that takes one argument. The function that takes one argument is returned by an anonymous, self-executing function that takes 2 arguments, the reference to the originalFunction before it is modified, and the reference to the callback function. These two function references become "locked" inside the closure so that when the originalFunction is then assigned a new value by the self-executing function, the legacyFn parameter still contains a reference to the originalFunction prior to it being modified.

In summary, at a higher level, originalFunction and myCallback are passed in as parameters to the self-executing anonymous function and are passed into the variables legacyFn and callback, and a new function is then assigned to originalFunction.

Now, when you call originalFunction('.someClassOnAnImage'), the legacyFn will fire, which will alert the selector and set the display property to none. Afterwards, the callback function, if it exists, will fire, and you'll then see:

The image with src = '.someClassOnAnImage' has been modified!

While this isn't as nice as a hypothetical or platform-specific addEventListener, it does allow you to modify the behavior of the functions in the legacy code without having to physically crack open those files and modify them. This simply extends the functions to perform additional behaviors but without needing to modify the original functions or even the original files for that matter.

You could neatly include all of your extensions in a separate JavaScript file (or whatever JavaScript file you're working in) and if you ever want to go back to the original behavior, you simply remove your extended functions.

like image 43
jmort253 Avatar answered Dec 29 '22 14:12

jmort253