是否可以使用Javascript检查样式标签内是否定义了某些CSS属性?

问题描述 投票:0回答:3

我正在编写一个脚本,需要检查

<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
顺便说一句。

javascript css styles
3个回答
7
投票

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

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
展平或
elementRules
,您仍然可以使用
for
循环并检查您需要什么。 它使用 ES5 函数和 matchesSelector,因此在旧浏览器中如果没有垫片就无法工作。另外,您还可以按优先级等进行过滤 - 例如,您可以删除所有优先级低于内联样式属性的属性等。


5
投票

您可以在 javascript 中完全探索 styleSheets

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


0
投票

我将@Zero 的答案更新为稍微更现代的代码。然而,我发现在 Chrome 中的 M1 Mac 上运行平均复杂的页面大约需要 20 毫秒。

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

© www.soinside.com 2019 - 2024. All rights reserved.