最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

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

programmeradmin3浏览0评论

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.

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.

Share Improve this question edited Apr 5, 2013 at 15:54 user1643156 asked Mar 27, 2013 at 19:10 user1643156user1643156 4,54711 gold badges41 silver badges59 bronze badges 6
  • "I'm not trying to get the getComputedStyle(ele).width btw." And yet, your code examples suggest that's exactly what you're trying to do. If it isn't, what are you trying to do? – T.J. Crowder Commented Mar 27, 2013 at 19:13
  • I'm trying to get some string (200px in this case) instead of "an empty string" from #bar since the style was defined in the style tag. – user1643156 Commented Mar 27, 2013 at 19:18
  • @ user: That's what getComputedStyle would do. – T.J. Crowder Commented Mar 27, 2013 at 19:20
  • 1 Crowder, please read the title, that's exactly what I'm trying to do. getComputedStyle will for sure return some real value, but you cannot tell where the style was defined, either from the style tag or inline style. @dystroy's suggestion might be the solution. – user1643156 Commented Mar 27, 2013 at 19:25
  • @ user: I saw the title. You need to understand that people say X and mean Y all the time. Yes, absolutely, look through the stylesheets if you think that's the best approach. Another might be to pare the style object to the return value from getComputedStyle. – T.J. Crowder Commented Mar 27, 2013 at 19:27
 |  Show 1 more ment

3 Answers 3

Reset to default 7

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.

You can pletely explore in javascript the styleSheets.

Start with the document.styleSheets array. The values are the different style elements or CSS files that are used by your document.

I updated @Zero's answer to slightly more modern code. However, I found that on averagely plex page it takes around 20ms to run on an M1 Mac in Chrome.

const slice = Function.call.bind(Array.prototype.slice)
const matches = Function.call.bind(Element.prototype.matches)

// Returns true if a DOM Element matches a cssRule
const elementMatchCSSRule = (element, cssRule) =>
  matches(element, cssRule.selectorText)

// Returns true if a property is defined in a cssRule
const propertyInCSSRule = (prop, cssRule) =>
  prop in cssRule.style && cssRule.style[prop] !== ''

// Here we get the cssRules across all the stylesheets in one array
const cssRules = slice(document.styleSheets).reduce(
  (rules, styleSheet) => [...rules, ...slice(styleSheet.cssRules)],
  [],
)

function hasSize(element) {
  // get only the css rules that matches that element
  const elementRules = cssRules.filter(elementMatchCSSRule.bind(null, element))

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

  return { hasWidth, hasHeight }
}

export default hasSize

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论