简体   繁体   English

检查css属性是否已应用!important属性

[英]Check if css property has !important attribute applied

If I have a style like this - 如果我有这样的风格 -

​div#testdiv {position:absolute;top:10px !important;}​

I can query the top value with jQuery like this - 我可以用这样的jQuery查询top值 -

$("#testdiv").css("top");

which will return the value 10px . 这将返回值10px Is it possible to use jQuery or JavaScript to check if the top property has had the !important attribute applied to it? 是否可以使用jQuery或JavaScript来检查top属性是否已应用!important属性?

First of all, such a solution does not seem to exist in jQuery. 首先,jQuery中似乎不存在这样的解决方案。

Many available javascript solutions offered, use the function getPropertyPriority() . 提供了许多可用的javascript解决方案,使用函数getPropertyPriority() First, this function is not supported by IE6-IE8 ( see here and here ). 首先,IE6-IE8不支持此功能(参见此处此处 )。 Second, this function does not directly work on elements if their style is not declared inline . 其次,如果元素的样式未声明为内联 ,则此函数不会直接对元素起作用。 So, we would be able to get the important property in the following case: 因此,我们将能够在以下情况下获得重要属性:

<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>

However if we could declare the style of #testdiv in a css stylesheet, we will get an empty string. 但是,如果我们可以在css样式表中声明#testdiv的样式,我们将得到一个空字符串。 Also the CSSStyleDeclaration interface is not available in IE6-8. IE6-8中也没有CSSStyleDeclaration接口。 Ofcourse this is pretty useless this way. 当然,这种方式很无用。 We need a different approach. 我们需要一种不同的方法。

I've put this approach into a JSFiddle . 我把这种方法放到JSFiddle中 We can read the !important property directly from the css stylesheets, which are contained in the array document.styleSheets[] . 我们可以直接从css样式表中读取!important属性,它们包含在数组document.styleSheets[] (Opera 8 and below do not support this array). (Opera 8及以下版本不支持此阵列)。 At Quirksmode you can see the methods which methods are supported to access the stylesheets. Quirksmode,您可以看到支持访问样式表的方法。 Based on this information we can do the following: 根据这些信息,我们可以执行以下操作:

  • For IE6-8, we use the styleSheets[].imports to access the imported stylesheets (and keep doing this recursively till we do not find any import statements anymore) and then styleSheets[].rules basically for each stylesheet add the css rules to an array. 对于IE6-8,我们使用styleSheets styleSheets[].imports .import来访问导入的样式表(并且继续执行此操作直到我们不再找到任何import语句)然后styleSheets[].rules基本上为每个样式表添加css规则到数组。
  • For other browsers, we use styleSheets[].cssRules to access both the imported and css rules. 对于其他浏览器,我们使用styleSheets[].cssRules来访问导入和css规则。 We detect the import rules by checking if it implements the CSSImportRule interface and use these to access the css rules in the imported stylesheets recursively. 我们通过检查它是否实现了CSSImportRule接口来检测导入规则,并使用它们以递归方式访问导入的样式表中的css规则。

In both cases we add the css rules to an array only if the rules matches the HTMLElement (in your case #testdiv ). 在这两种情况下,只有当规则与HTMLElement匹配时(在您的情况下为#testdiv ),我们才将css规则添加到数组中。 This results in an array of css rules that are matched to a HTMLElement. 这会产生一系列与HTMLElement匹配的css规则。 This is basically what the getMatchedCSSRules() function in webkit browsers does. 这基本上是webkit浏览器中的getMatchedCSSRules()函数所做的。 However, we write it ourselves here. 但是,我们自己在这里写。

Based on this information we write our hasImportant(htmlNode, property) function, where htmlNode is an HTMLElement (your testdiv) and property the css property ('top' in your case). 根据这些信息,我们编写了hasImportant(htmlNode, property)函数,其中htmlNode是一个HTMLElement(你的testdiv),属性是css属性(在你的情况下是'top')。 First, we check if the inline style of the top property has an important attribute. 首先,我们检查top属性的内联样式是否具有重要属性。 This saves us looking through the stylesheets if it does contain this attribute. 如果它包含此属性,这可以节省我们查看样式表的时间。

We write a new function isImportant(node, property) which uses our good old function node.style.getPropertyPriority(property) . 我们编写了一个新函数isImportant(node, property) ,它使用了我们很好的旧函数node.style.getPropertyPriority(property) However, like I mentioned earlier in this answer: this function is not supported in IE6-IE8. 但是,正如我在本回答中提到的那样:IE6-IE8不支持此功能。 We can write the function ourselves: in IE the property node.style.cssText contains the declaration block text. 我们可以自己编写函数:在IE中,属性node.style.cssText包含声明块文本。 We search for the property ('top') in this block of text and check if its value contains '!important'. 我们在这个文本块中搜索属性('top')并检查它的值是否包含'!important'。 We can reuse this function on every css rule obtained using the getMatchedCSSRules function, by looping through all css rules that match with the htmlNode and calling the isImportant function. 我们可以在使用getMatchedCSSRules函数获得的每个css规则上重用此函数,方法是循环遍历与htmlNode匹配的所有css规则并调用isImportant函数。

All of the above can be found in the code below. 以上所有内容均可在以下代码中找到。 This is the basic approach and probably should be fine-tuned further: 这是基本方法,可能应进一步微调:

  • some code might be replaced with jQuery 一些代码可能会被jQuery取代
  • some code might be simplified 一些代码可能会被简化
  • css rules implementing the CSSMediaRule interface and other interfaces might cause some problems for this code and an error check should be performed 实现CSSMediaRule接口和其他接口的 css规则可能会导致此代码出现一些问题,并应执行错误检查
  • there might be simpler approach, but I am not aware of any other method to get this working cross browser. 可能有更简单的方法,但我不知道任何其他方法来使这个工作跨浏览器。

     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'); }); 

See How to apply !important using .css()? 请参阅如何申请!重要使用.css()?

There's a function there that you can add to jQuery. 那里有一个函数可以添加到jQuery中。 Then you use it like this: 然后你像这样使用它:

console.log($('#testdiv').style().getPropertyPriority('top'));

you can try reading it directly from the css style sheet. 您可以尝试直接从css样式表中读取它。

have a look at the second answer of this question: get CSS rule's percentage value in jQuery 看看这个问题的第二个答案: 在jQuery中获取CSS规则的百分比值

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM