14

こんなスタイルだったら…

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

topこのようにjQueryで値を照会できます-

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

値を返します10px。jQuery または JavaScript を使用して、 topプロパティに!important属性が適用されているかどうかを確認することはできますか?

4

3 に答える 3

9

まず第一に、そのような解決策は jQuery には存在しないようです。

提供される多くの利用可能な JavaScript ソリューションでは、関数を使用しますgetPropertyPriority()。まず、この関数は IE6 ~ IE8 ではサポートされていません (ここここを参照)。次に、スタイルが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>

#testdivただし、css スタイルシートでのスタイルを宣言できる場合は、空の文字列が返されます。また、このCSSStyleDeclarationインターフェイスは IE6-8 では使用できません。もちろん、これはこの方法ではかなり役に立ちません。別のアプローチが必要です。

このアプローチをJSFiddleに入れました。array に含まれる css スタイルシートから !important プロパティを直接読み取ることができますdocument.styleSheets[]。(Opera 8 以下はこの配列をサポートしていません)。Quirksmodeで、スタイルシートにアクセスするためにサポートされているメソッドを確認できますこの情報に基づいて、次のことができます。

  • IE6-8 では、 を使用しstyleSheets[].importsてインポートされたスタイルシートにアクセスし (インポート ステートメントが見つからなくなるまでこれを再帰的に続けます)、styleSheets[].rules基本的にスタイルシートごとに CSS ルールを配列に追加します。
  • 他のブラウザーではstyleSheets[].cssRules、インポートされたルールと CSS ルールの両方にアクセスするために使用します。インポート ルールがCSSImportRuleインターフェイスを実装しているかどうかを確認することでインポート ルールを検出し、これらを使用して、インポートされたスタイルシートの CSS ルールに再帰的にアクセスします。

どちらの場合も、ルールが HTMLElement に一致する場合にのみ、css ルールを配列に追加します (あなたの場合は#testdiv)。これにより、HTMLElement に一致する CSS ルールの配列が生成されます。これは基本的にgetMatchedCSSRules()、Webkit ブラウザーの関数が行うことです。ただし、ここでは自分で書きます。

この情報に基づいて、hasImportant(htmlNode, property)関数を記述します。ここで、htmlNode は HTMLElement (あなたの testdiv) で、プロパティは css プロパティ (あなたの場合は 'top') です。まず、最上位プロパティのインライン スタイルに重要な属性があるかどうかを確認します。これにより、この属性が含まれている場合にスタイルシートを調べる手間が省けます。

isImportant(node, property)古き良き関数を使用する新しい関数を作成しますnode.style.getPropertyPriority(property)。ただし、この回答で前述したように、この関数は IE6-IE8 ではサポートされていません。関数を自分で書くことができます。IE では、プロパティnode.style.cssTextに宣言ブロック テキストが含まれます。このテキスト ブロックでプロパティ ('top') を検索し、その値に '!important' が含まれているかどうかを確認します。getMatchedCSSRuleshtmlNode と一致するすべての css ルールをループして isImportant 関数を呼び出すことにより、この関数を使用して取得したすべての css ルールでこの関数を再利用できます。

上記のすべては、以下のコードで見つけることができます。これは基本的なアプローチであり、おそらくさらに微調整する必要があります。

  • 一部のコードは 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');
    });
    
于 2012-04-25T22:37:16.010 に答える
6

.css() を使用して !important を適用する方法を参照してください。

jQueryに追加できる関数があります。次に、次のように使用します。

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

于 2012-04-25T10:53:54.437 に答える
1

css スタイル シートから直接読み取ってみることができます。

この質問の 2 番目の回答を見てください: jQuery で CSS ルールのパーセンテージ値を取得する

于 2012-04-25T10:53:09.457 に答える