I had to think about this for a min or two; nice.
i think your code would be more managble in a re-usable function, which isn't that difficult to work-up. the question, is do you wan't power or compatibility? if you can re-use the existing style object, all tools for animation should drop right in. That's power. If this isn't something that needs a bevy of existing tools, having a new element property by which to manipulate style isn't a big deal. Indeed, you code uses object.display instead of object.style.display.
the power version works in webkit, but not in FF:, which is sad because this version is invisible: it replaces element.style with a stand-in shadow.
Code:
function watchStyle(element, property, changeCallback){
if(!element.style2){
element.style2=element.style;
delete element.style;
element.style={};
}
delete element.style[property];
Object.defineProperty( element.style, property, { configurable: true,
get: function(){return element.style2[property]; },
set: function(val){
var cStyle=element.style2[property];
if( val==cStyle){return false;} // throw away duplicates
element.style2[property]=val; // set actual style object
changeCallback.call(element, property, val);
},
});
}
// Let's test it:
watchStyle(document.body, "color", function demoCB(prop, value){
alert(prop +" changed to "+value);
});
// invoke watcher
document.body.style.color="blue";
// invoke watcher
document.body.style.color="red";
// invoke watcher (NOT!)
document.body.style.color="red";
// invoke watcher
document.body.style.color="blue";
there reason firefox rejects it is becasue it won't allow element.style to be deleted or replaced in whole, but webkit does...
giving up the cool factor, we can still accomplish the goal cross browser by using a property other than style. let's call it style2 for lack of imagination.
once you setup the subscription using watchStyle(), you then set style2.display instead of style.display, or whatever property you are monitoring:
Code:
function watchStyle(element, property, changeCallback){
var pool= (element.style2=element.style2||{});
delete pool[property];
Object.defineProperty(pool, property, { configurable: true,
get: function(){return element.style[property]; },
set: function(val){
var cStyle=element.style[property];
if(val==cStyle){return false;} // throw away duplicates
element.style[property]=val;
changeCallback.call(element, property, val, cStyle);
},
});
}
watchStyle(document.body, "color", function demoCB(prop, value, previousValue){
alert(prop +" changed to "+value+" on "+this.outerHTML.split(">")[0].slice(0,25));
});
//demo test: should alert "red", then "blue", then be done.
document.body.style2.color="red";
document.body.style2.color="blue";
document.body.style2.color="blue"; // but not this time, it's a duplicate...
tested ff, ch, ie9