2012-04-25 87 views
12

如果我有这样的风格 -检查CSS属性具有重要的属性应用于

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

我可以用jQuery查询top值这样的 -

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

这将返回值10px。是否有可能使用jQuery或JavaScript来检查top属性是否已应用!important属性?

+0

这样的:div.style()getPropertyPriority( '顶')?您可能感兴趣:http://www.quirksmode.org/dom/tests/cssMisc.html。不过,不是jQuery解决方案。 – 2012-04-25 11:05:56

回答

8

首先,这样的解决方案似乎并没有在jQuery的存在。

提供了许多可用的javascript解决方案,使用函数getPropertyPriority()。首先,IE6-IE8不支持此功能(请参阅herehere)。其次,如果它们的样式未声明,则此功能不直接适用于元素内联。因此,我们将能够获得重要的特性在下面的情况:

<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。我们可以直接从数组document.styleSheets[]中包含的css样式表中读取!important属性。 (Opera 8及以下版本不支持这个阵列)。在Quirksmode你可以看到支持访问样式表的方法。基于这些信息,我们可以做到以下几点:

  • 对于IE6-8,我们使用styleSheets[].imports访问导入的样式表(并保持递归这样做,直到我们没有找到任何import语句了),然后styleSheets[].rules基本上为每个样式表添加css规则到一个数组。
  • 对于其他浏览器,我们使用styleSheets[].cssRules来访问导入规则和css规则。我们通过检查它是否实现了接口并使用它们来递归访问导入的样式表中的css规则来检测导入规则。

在这两种情况下,只要规则匹配HTMLElement(在您的案例#testdiv),我们就会将css规则添加到数组中。这会产生一个与HTMLElement匹配的css规则数组。这基本上是webkit浏览器中getMatchedCSSRules()函数的作用。但是,我们自己在这里写。

根据这些信息,我们编写我们的hasImportant(htmlNode, property)函数,其中htmlNode是一个HTMLElement(你的testdiv)并且属性是css属性(在你的案例中是'top')。首先,我们检查顶层属性的内联样式是否具有重要属性。这节省了我们查看样式表,如果它包含此属性的话。

我们写了一个新功能isImportant(node, property)它使用我们的老功能node.style.getPropertyPriority(property)。但是,就像我在前面提到的那样:IE6-IE8不支持该功能。我们可以自己编写函数:在IE中,属性node.style.cssText包含声明块文本。我们在这个文本块中搜索属性('top')并检查它的值是否包含'!important'。我们可以在使用getMatchedCSSRules函数获得的每个css规则中循环使用此函数,方法是循环所有与htmlNode匹配的css规则并调用isImportant函数。

以上所有都可以在下面的代码中找到。这是基本的做法,而且也应该进一步微调:

  • 一些代码可能使用jQuery来代替
  • 一些代码可能会被简化,实现CSSMediaRule接口和
  • CSS规则other interfaces可能会引起一些问题对于此代码和应执行错误检查
  • 可能有更简单的方法,但我不知道有任何其他方法来获得此工作的跨浏览器。

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

很好@dennisg +1 – 2012-04-26 04:42:57

6

How to apply !important using .css()?

有一个功能那里,你可以添加到jQuery的。然后你使用这样的:

所有的

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

+1

这不适用于我,请参阅 - http://jsfiddle.net/74MCx/。如果我通过函数的set方法设置CSS值,但不能用CSS中声明的样式(返回一个空字符串),该函数将起作用。 – ipr101 2012-04-25 12:21:48

+0

像@dennisg说的那样:它显然只适用于元素内嵌的样式:((即

Hello
) – Tobbe 2012-04-27 07:44:53