This works for me...
Use a mutation observer to catch changes to the style attribute...
var observer = new MutationObserver(parseMutations); observer.observe(document, { ... attributes: true, attributeFilter: ["style"] }); ... if (mutation.attributeName) //we'll assume it's "style" parseNode(mutation.target); //check for style.backgroundImage and call filterNode()
This works for both
setAttribute("style", ...)
andelement.style.whatever = something
.Catch new
style
andlink
elements with the mutation observer, add anonload
event and parse applicable nodes...var stylenodes = ["STYLE", "LINK"]; ... for (var i = 0; i < mutation.addedNodes.length; i++) { var node = mutation.addedNodes[i]; var nodeName = node.nodeName.toUpperCase(); if (stylenodes.indexOf(nodeName) !== -1) node.addEventListener("load", styleLoaded); ... //catch loading of stylenodes and parse all new rules var currentLoadedStyles = []; var styleLoaded = function() { //check all styles and look for one that has just added some rules for (var i = 0; i < document.styleSheets.length; ++i) { if (document.styleSheets[i].rules && document.styleSheets[i].rules.length > 0 && currentLoadedStyles.indexOf(document.styleSheets[i]) == -1) { currentLoadedStyles.push(document.styleSheets[i]); parseNewStyle(document.styleSheets[i].rules); } } }; //look for rules with background images and re-filter all nodes it applies to var parseNewStyle = function(rules) { for (var i = 0; i < rules.length; ++i) { //if any rule contains a background-image (could look for anything here really) if (rules[i].style && rules[i].style.backgroundImage && rules[i].style.backgroundImage != "none") { //get all affected nodes and re-parse them var nodes = document.querySelectorAll(rules[i].selectorText); for (var j = 0; j < nodes.length; ++j) filterNode(nodes[j]); } } };