【问题标题】:Is it possible to check if certain CSS properties are defined inside the style tag with Javascript?是否可以使用 Javascript 检查是否在样式标签内定义了某些 CSS 属性?
【发布时间】:2013-03-27 19:10:54
【问题描述】:

我正在编写一个脚本,它需要检查是否在 <style> 标记内定义了某些 CSS 属性。

<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) {
    // ...
}

这可能吗?

我不是想得到getComputedStyle(ele).width btw。

【问题讨论】:

  • “我不是想得到 getComputedStyle(ele).width 顺便说一句。” 然而,你的代码示例表明这正是你想要做的。如果不是,你想做什么
  • 我正在尝试从 #bar 获取一些字符串(在这种情况下为 200px)而不是“空字符串”,因为样式是在样式标签中定义的。
  • @用户:getComputedStyle 会这样做。
  • 克劳德,请阅读标题,这正是我想要做的。 getComputedStyle 肯定会返回一些实际值,但是您无法从样式标记或内联样式中判断样式的定义位置。 @dystroy 的建议可能是解决方案。
  • @用户:我看到标题了。您需要了解人们总是说 X 表示 Y。是的,当然,如果您认为这是最好的方法,请查看样式表。另一个可能是将style 对象与getComputedStyle 的返回值进行比较。

标签: javascript css styles


【解决方案1】:

我不确定这是你想要的,它最接近你的第一个伪代码,你有一个元素实例,无论如何希望它有所帮助:

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"));

我认为您可以为您的目的重用所有这些代码,或者只是其中的一部分,它是有目的的模块化 - 例如,一旦您拥有所有 cssRules flatten 或 elementRules,您仍然可以使用for 循环并检查您需要什么。 它使用 ES5 函数和matchesSelector,因此在旧浏览器中没有垫片将无法工作。另外,您还可以按优先级等进行过滤 - 例如,您可以删除所有优先级低于内联样式的属性,等等。

【讨论】:

  • ZER0,我还是不太明白你的代码是如何工作的。但是,这正是我想要的。最好的部分是它适用于parent child {prop: val},其中 child 是元素标签名称,而不是类或 id 选择器。回答接受。非常感谢。
  • 我尝试在代码中添加一些有意义的 cmets,但如果您想更好地解释某些部分,请告诉我。很高兴这是您正在寻找的代码!
  • 我在这里更新了你的代码的修改版本:stackoverflow.com/questions/50567761/…也许你会想看看!
  • @TakitIsy 嘿,谢谢!很高兴看到它仍然有用且有帮助。 :)
【解决方案2】:

您可以在 javascript 中完全探索styleSheets

document.styleSheets 数组开始。这些值是您的文档使用的不同样式元素或 CSS 文件。

【讨论】:

  • 我正在查看文档...看来我必须在每个样式表上执行正则表达式。一个小的修正...document.styleSheetsS 大写 Sheets
  • 你为什么要做正则表达式? reading styleSheets from js时我当然不需要正则表达式。
  • 这是我在控制台登录document.styleSheets 时的第一个想法。问题已解决,问题已更新。谢谢。
  • dystroy,感谢 styleSheets 提示。我发现 ZER0 的解决方案正是我所需要的。所以我选择了他的答案作为接受。对此感到抱歉。
猜你喜欢
  • 2021-10-03
  • 1970-01-01
  • 2013-01-31
  • 1970-01-01
  • 1970-01-01
  • 2012-07-15
  • 1970-01-01
  • 2012-05-06
相关资源
最近更新 更多