如果我有這樣的風格 -檢查CSS屬性具有重要的屬性應用於
div#testdiv {position:absolute;top:10px !important;}
我可以用jQuery查詢top
值這樣的 -
$("#testdiv").css("top");
這將返回值10px
。是否有可能使用jQuery或JavaScript來檢查top
屬性是否已應用!important
屬性?
如果我有這樣的風格 -檢查CSS屬性具有重要的屬性應用於
div#testdiv {position:absolute;top:10px !important;}
我可以用jQuery查詢top
值這樣的 -
$("#testdiv").css("top");
這將返回值10px
。是否有可能使用jQuery或JavaScript來檢查top
屬性是否已應用!important
屬性?
首先,這樣的解決方案似乎並沒有在jQuery的存在。
提供了許多可用的javascript解決方案,使用函數getPropertyPriority()
。首先,IE6-IE8不支持此功能(請參閱here和here)。其次,如果它們的樣式未聲明,則此功能不直接適用於元素內聯。因此,我們將能夠獲得重要的特性在下面的情況:
<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你可以看到支持訪問樣式表的方法。基於這些信息,我們可以做到以下幾點:
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函數。
以上所有都可以在下面的代碼中找到。這是基本的做法,而且也應該進一步微調:
可能有更簡單的方法,但我不知道有任何其他方法來獲得此工作的跨瀏覽器。
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');
});
很好@dennisg +1 – 2012-04-26 04:42:57
你可以嘗試直接從CSS樣式表中讀取它。
看看這個問題的第二個答案: get CSS rule's percentage value in jQuery
見How to apply !important using .css()?
有一個功能那裏,你可以添加到jQuery的。然後你使用這樣的:
所有的console.log($('#testdiv').style().getPropertyPriority('top'));
這樣的:div.style()getPropertyPriority( '頂')?您可能感興趣:http://www.quirksmode.org/dom/tests/cssMisc.html。不過,不是jQuery解決方案。 – 2012-04-25 11:05:56