如果我有这样的风格 -
div#testdiv {position:absolute;top:10px !important;}
我可以使用jQuery查询top
值 -
$("#testdiv").css("top");
将返回值10px
。是否可以使用jQuery或JavaScript来检查top
属性是否已应用!important
属性?
答案 0 :(得分:8)
首先,jQuery中似乎不存在这样的解决方案。
提供了许多可用的javascript解决方案,使用函数getPropertyPriority()
。首先,IE6-IE8不支持此功能(请参阅here和here)。其次,如果未将其样式声明为 inline ,则此函数不会直接对元素起作用。因此,我们将能够在以下情况下获得重要属性:
<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
的样式,我们将得到一个空字符串。 IE6-8中也没有CSSStyleDeclaration
接口。当然,这种方式很无用。我们需要一种不同的方法。
我已将此方法放入JSFiddle。我们可以直接从css样式表中读取!important属性,这些样式表包含在数组document.styleSheets[]
中。 (Opera 8及以下版本不支持此阵列)。在Quirksmode,您可以看到支持访问样式表的方法。根据这些信息,我们可以执行以下操作:
styleSheets[].imports
来访问导入的样式表(并且继续执行此操作直到我们不再找到任何import语句)然后styleSheets[].rules
基本上为每个样式表添加css规则到数组。styleSheets[].cssRules
来访问导入和css规则。我们通过检查导入规则是否实现 CSSImportRule 接口来检测导入规则,并使用它们以递归方式访问导入的样式表中的css规则。在这两种情况下,只有当规则与HTMLElement匹配时(在您的情况下为#testdiv
),我们才会将css规则添加到数组中。这会产生一系列与HTMLElement匹配的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函数。
以上所有内容均可在以下代码中找到。这是基本方法,可能应该进一步微调:
可能有更简单的方法,但我不知道有任何其他方法可以使这个跨浏览器工作。
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');
});
答案 1 :(得分:6)
请参阅How to apply !important using .css()?
那里有一个可以添加到jQuery的函数。然后你就像这样使用它:
console.log($('#testdiv').style().getPropertyPriority('top'));
答案 2 :(得分:1)
您可以尝试直接从css样式表中阅读。
看看这个问题的第二个答案: get CSS rule's percentage value in jQuery