检查 css 属性是否应用了 !重要属性
Check if css property has !important attribute applied
如果我有这样的风格——
div#testdiv {position:absolute;top:10px !important;}
我可以像这样使用 jQuery 查询top
值 -
$("#testdiv").css("top");
这将返回值10px
.是否可以使用 jQuery 或 JavaScript 来检查 top
属性是否应用了 !important
属性?
首先,这样的解决方案在jQuery中似乎不存在。
提供了许多可用的JavaScript解决方案,使用函数getPropertyPriority()
。首先,IE6-IE8不支持此功能(请参阅此处和此处)。其次,如果元素的样式未内联声明,则此函数不直接处理元素。因此,在以下情况下,我们将能够获得重要属性:
<div id="testdiv" style="top : 10px !important;">Some div</div>
<script type="text/javascript">
// should show 'important' in the console.
console.log(document.getElementById("testdiv").style.getPropertyPriority('top'));
</script>
但是,如果我们可以在 css 样式表中声明#testdiv
样式,我们将得到一个空字符串。此外,CSSStyleDeclaration
接口在IE6-8中不可用。当然,这样是没有用的。我们需要一种不同的方法。
我已经将这种方法放入JSFiddle中。我们可以直接从包含在数组document.styleSheets[]
中的 css 样式表中读取 !important 属性。(Opera 8 及更低版本不支持此数组)。在Quirksmode中,您可以看到支持哪些方法访问样式表的方法。根据这些信息,我们可以执行以下操作:
- 对于IE6-8,我们使用
styleSheets[].imports
来访问导入的样式表(并继续递归地执行此操作,直到我们不再找到任何导入语句),然后基本上styleSheets[].rules
为每个样式表将css规则添加到数组中。 - 对于其他浏览器,我们使用
styleSheets[].cssRules
来访问导入的规则和 css 规则。我们通过检查导入规则是否实现了 CSSImportRule 接口来检测导入规则,并使用这些规则递归访问导入样式表中的 css 规则。
在这两种情况下,我们仅在规则与 HTML 匹配时才将 css 规则添加到数组中(在您的情况下#testdiv
)。这会产生与 HTML 环境匹配的 css 规则数组。这基本上就是webkit浏览器中的getMatchedCSSRules()
功能所做的。但是,我们在这里自己写。
基于这些信息,我们编写了hasImportant(htmlNode, property)
函数,其中htmlNode是一个HTMLElement(你的testdiv),属性是css属性(在你的例子中是"top")。首先,我们检查 top 属性的内联样式是否具有重要属性。这样可以节省我们查看样式表是否包含此属性的情况。
我们编写一个新的函数isImportant(node, property)
它使用我们很好的旧函数node.style.getPropertyPriority(property)
。但是,就像我之前在这个答案中提到的:IE6-IE8不支持此功能。我们可以自己编写函数:在IE中,属性node.style.cssText
包含声明块文本。我们在此文本块中搜索属性("top"),并检查其值是否包含"!important"。我们可以在使用 getMatchedCSSRules
函数获取的每个 css 规则上重用此函数,方法是遍历与 htmlNode 匹配的所有 css 规则并调用 isImportant 函数。
以上所有内容都可以在下面的代码中找到。这是基本方法,可能应该进一步微调:
- 某些代码可能会替换为 jQuery
- 某些代码可能会简化
- 实现 CSSMediaRule 接口和其他接口的 css 规则可能会导致此代码出现一些问题,应执行错误检查
可能有更简单的方法,但我不知道任何其他方法可以让这个跨浏览器工作。
var debug = true; /** * Get the css rules of a stylesheet which apply to the htmlNode. Meaning its class * its id and its tag. * @param CSSStyleSheet styleSheet * @param HTMLElement htmlNode */ function getCssRules(styleSheet, htmlNode) { if ( !styleSheet ) return null; var cssRules = new Array(); if (styleSheet.cssRules) { var currentCssRules = styleSheet.cssRules; // Import statement are always at the top of the css file. for ( var i = 0; i < currentCssRules.length; i++ ) { // cssRules all contains the import statements. // check if the rule is an import rule. if ( isImportRule(currentCssRules[i]) ) { // import the rules from the imported css file. var importCssRules = getCssRules(currentCssRules[i].styleSheet, htmlNode); if ( importCssRules != null ) { // Add the rules from the import css file to the list of css rules. cssRules = addToArray(cssRules, importCssRules, htmlNode); } // Remove the import css rule from the css rules. styleSheet.deleteRule(i); } else { // We found a rule that is not an CSSImportRule break; } } // After adding the import rules (lower priority than those in the current stylesheet), // add the rules in the current stylesheet. cssRules = addToArray(cssRules, currentCssRules, htmlNode); } else if (styleSheet.rules) { // IE6-8 // rules do not contain the import statements. var currentCssRules = styleSheet.rules; // Handle the imports in a styleSheet file. if ( styleSheet.imports ) { // IE6-8 use a seperate array which contains the imported css files. var imports = styleSheet.imports; for ( var i = 0; i < imports.length; i++ ) { var importCssRules = getCssRules(imports[i], htmlNode); if ( importCssRules != null ) { // Add the rules from the import css file to the list of css rules. cssRules = addToArray(cssRules, importCssRules, htmlNode); } } } // After adding the import rules (lower priority than those in the current stylesheet), // add the rules in the current stylesheet. cssRules = addToArray(cssRules, currentCssRules, htmlNode); } return cssRules; } /** * Since a list of rules is returned, we cannot use concat. * Just use old good push.... * @param CSSRuleList cssRules * @param CSSRuleList cssRules * @param HTMLElement htmlNode */ function addToArray(cssRules, newRules, htmlNode) { for ( var i = 0; i < newRules.length; i++ ) { if ( htmlNode != undefined && htmlNode != null && isMatchCssRule(htmlNode, newRules[i]) ) cssRules.push(newRules[i]); } return cssRules; } /** * Matches a htmlNode to a cssRule. If it matches, return true. * @param HTMLElement htmlNode * @param CSSRule cssRule */ function isMatchCssRule(htmlNode, cssRule) { // Simply use jQuery here to see if there cssRule matches the htmlNode... return $(htmlNode).is(cssRule.selectorText); } /** * Verifies if the cssRule implements the interface of type CSSImportRule. * @param CSSRule cssRule */ function isImportRule(cssRule) { return cssRule.constructor.toString().search("CSSImportRule") != -1; } /** * Webkit browsers contain this function, but other browsers do not (yet). * Implement it ourselves... * * Finds all matching CSS rules for the htmlNode. * @param HTMLElement htmlNode */ function getMatchedCSSRules(htmlNode) { var cssRules = new Array(); // Opera 8- don't support styleSheets[] array. if ( !document.styleSheets ) return null; // Loop through the stylesheets in the html document. for ( var i = 0; i < document.styleSheets.length; i++ ) { var currentCssRules = getCssRules(document.styleSheets[i], htmlNode) if ( currentCssRules != null ) cssRules.push.apply(cssRules, currentCssRules); } return cssRules; } /** * Checks if the CSSStyleRule has the property with 'important' attribute. * @param CSSStyleRule node * @param String property */ function isImportant(node, property) { if ( node.style.getPropertyPriority && node.style.getPropertyPriority(property) == 'important' ) return true; else if ( node.style.cssText && getPropertyPriority(node.style.cssText, property) == 'important' ) { // IE6-8 // IE thinks that cssText is part of rule.style return true; } } /** * getPropertyPriority function for IE6-8 * @param String cssText * @param String property */ function getPropertyPriority(cssText, property) { var props = cssText.split(";"); for ( var i = 0; i < props.length; i++ ) { if ( props[i].toLowerCase().indexOf(property.toLowerCase()) != -1 ) { // Found the correct property if ( props[i].toLowerCase().indexOf("!important") != -1 || props[i].toLowerCase().indexOf("! important") != -1) { // IE automaticaly adds a space between ! and important... return 'important'; // We found the important property for the property, return 'important'. } } } return ''; // We did not found the css property with important attribute. } /** * Outputs a debug message if debugging is enabled. * @param String msg */ function debugMsg(msg) { if ( debug ) { // For debugging purposes. if ( window.console ) console.log(msg); else alert(msg); } } /** * The main functionality required, to check whether a certain property of * some html element has the important attribute. * * @param HTMLElement htmlNode * @param String property */ function hasImportant(htmlNode, property) { // First check inline style for important. if ( isImportant(htmlNode, property) ) { // For debugging purposes. debugMsg("Inline contains important!"); return true; } var rules = getMatchedCSSRules(htmlNode); if ( rules == null ) { debugMsg("This browser does not support styleSheets..."); return false; } /** * Iterate through the rules backwards, since rules are * ordered by priority where the highest priority is last. */ for ( var i = rules.length; i-- > 0; ) { var rule = rules[i]; if ( isImportant(rule, property) ) { // For debugging purposes. debugMsg("Css contains important!"); return true; } } return false; } $(document).ready(function() { hasImportant($('#testdiv')[0], 'top'); });
请参阅如何使用 .css() 应用 !important?
那里有一个函数可以添加到jQuery中。然后你像这样使用它:
console.log($('#testdiv').style().getPropertyPriority('top'));
尝试直接从CSS样式表中读取它。
看看这个问题的第二个答案:在 jQuery 中获取 CSS 规则的百分比值
- 有条件地在选项标记中应用布尔属性
- 表单's的action属性-如何在javascript中指定完整的应用程序路径
- CSS根据属性的可用性有条件地应用样式
- 如何在不链接/jquery的情况下使用方法应用css属性数组
- vendors.js:未捕获类型错误:无法读取属性'应用'使用webpack时未定义的
- 使用 SharePoint 查询字符串值作为应用程序部件属性
- 我把“;类“;SVG中存在但未应用的节点的属性!为什么?
- javascript对象属性应用于所有对象
- 如何在单击时将 css 属性应用于选项卡
- 将 CSS 属性应用于具有 JS 中变量的图像
- D3 缩放 - 无法读取未定义的属性“应用”
- 在 JavaScript 中将基类型的属性应用于子类型
- 如何在 Javascript 中使用元素的 CSS 路径将 CSS 属性应用于元素
- 此脚本将特定属性应用于网站上的所有链接.如何排除pdf和zip文件
- 无法通过XML中的类属性应用CSS
- 在javascript中通过class属性应用样式时是否有限制?
- element.appendChild(node)是否将父节点的属性应用到子节点
- 如何将属性应用于存在但不立即可见的Titanium元素
- 如何对下拉列表项的标题属性应用样式
- 将属性应用于存储在jQuery包装器中的变量中的嵌套标记