gpt4 book ai didi

javascript - 检查 css 属性是否应用了 !important 属性

转载 作者:可可西里 更新时间:2023-11-01 02:05:56 25 4
gpt4 key购买 nike

如果我有这样的风格——

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

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

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

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

最佳答案

首先,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 的样式,我们将得到一个空字符串。此外,CSSStyleDeclaration 接口(interface)在 IE6-8 中不可用。当然,这种方式毫无用处。我们需要一种不同的方法。

我已将此方法放入 JSFiddle 中.我们可以直接从包含在数组 document.styleSheets[] 中的 css 样式表中读取 !important 属性。 (Opera 8 及以下版本不支持此数组)。在 Quirksmode您可以看到支持访问样式表的方法。根据这些信息,我们可以执行以下操作:

  • 对于 IE6-8,我们使用 styleSheets[].imports 访问导入的样式表(并以递归方式继续执行此操作,直到我们不再找到任何导入语句),然后使用 styleSheets [].rules 基本上为每个样式表将 css 规则添加到数组。
  • 对于其他浏览器,我们使用 styleSheets[].cssRules 来访问导入规则和 css 规则。我们通过检查它是否实现了 CSSImportRule 接口(interface)来检测导入规则,并使用它们以递归方式访问导入样式表中的 css 规则。

在这两种情况下,我们仅在规则与 HTMLElement 匹配时才将 css 规则添加到数组(在您的情况下为 #testdiv)。这会生成一组与 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 包含声明 block 文本。我们在此文本 block 中搜索属性 ('top') 并检查其值是否包含 '!important'。我们可以在使用 getMatchedCSSRules 函数获得的每个 css 规则上重用此函数,方法是遍历与 htmlNode 匹配的所有 css 规则并调用 isImportant 函数。

以上所有内容都可以在下面的代码中找到。这是基本方法,可能应该进一步微调:

  • 一些代码可能会被 jQuery 取代
  • 一些代码可能会被简化
  • CSS 规则实现 CSSMediaRule 接口(interface)和 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');
    });

关于javascript - 检查 css 属性是否应用了 !important 属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10314131/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com