Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to check if certain CSS properties are defined inside the style tag with Javascript?

I'm writing a script that needs to check if certain CSS properties are defined inside the <style> tag.

<style type="text/css">
#bar {width: 200px;}
</style>
<div id="foo" style="width: 200px;">foo</div>
<div id="bar">bar</div>
// 200px
console.log(document.getElementById("foo").style.width);

// an empty string
console.log(document.getElementById("bar").style.width);

if(property_width_defined_in_style_tag) {
    // ...
}

Is this possible?

I'm not trying to get the getComputedStyle(ele).width btw.

like image 218
user1643156 Avatar asked Dec 20 '22 07:12

user1643156


1 Answers

I'm not sure this is what you want, it works closest to your first pseudo code where you had an element instance, anyway hope it helps:

var proto = Element.prototype;
var slice = Function.call.bind(Array.prototype.slice);
var matches = Function.call.bind(proto.matchesSelector || 
                proto.mozMatchesSelector || proto.webkitMatchesSelector ||
                proto.msMatchesSelector || proto.oMatchesSelector);

// Returns true if a DOM Element matches a cssRule
var elementMatchCSSRule = function(element, cssRule) {
  return matches(element, cssRule.selectorText);
};

// Returns true if a property is defined in a cssRule
var propertyInCSSRule = function(prop, cssRule) {
  return prop in cssRule.style && cssRule.style[prop] !== "";
};

// Here we get the cssRules across all the stylesheets in one array
var cssRules = slice(document.styleSheets).reduce(function(rules, styleSheet) {
  return rules.concat(slice(styleSheet.cssRules));
}, []);

// get a reference to an element, then...
var bar = document.getElementById("bar");

// get only the css rules that matches that element
var elementRules = cssRules.filter(elementMatchCSSRule.bind(null, bar));

// check if the property "width" is in one of those rules
hasWidth = elementRules.some(propertyInCSSRule.bind(null, "width"));

I think you can reuse all of this code for your purpose, or just some piece of it, it's modular on purpose – for instance, once you have all the cssRules flatten, or the elementRules, you can still use a for loop and check what you need. It uses ES5 functions and matchesSelector so in old browsers won't work without shims. Plus, you could also filter by priority and so on – you could for instance remove all the properties has a lower priority than the inline style ones, etc.

like image 147
ZER0 Avatar answered Jan 21 '23 13:01

ZER0