查找适用于元素的所有CSS规则
许多工具/ API提供了select特定类或ID的元素的方法。 还可以检查浏览器加载的原始样式表。
但是,对于浏览器渲染元素,他们将编译所有CSS规则(可能来自不同的样式表文件)并将其应用于元素。 这就是你用Firebug或WebKit Inspector所看到的 – 一个元素的完整的CSSinheritance树。
如何在纯JavaScript中重现此function,而无需额外的浏览器插件?
也许一个例子可以提供一些我正在寻找的澄清:
<style type="text/css"> p { color :red; } #description { font-size: 20px; } </style> <p id="description">Lorem ipsum</p>
这里的p#description元素有两个CSS规则:红色和20px的字体大小。
我想从这些计算出来的CSS规则来源(颜色来自P规则等等)。
由于这个问题目前没有轻量级(非库),跨浏览器兼容的答案,我会尽量提供一个:
function css(el) { var sheets = document.styleSheets, ret = []; el.matches = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector || el.oMatchesSelector; for (var i in sheets) { var rules = sheets[i].rules || sheets[i].cssRules; for (var r in rules) { if (el.matches(rules[r].selectorText)) { ret.push(rules[r].cssText); } } } return ret; }
JSFiddle: http : //jsfiddle.net/HP326/6/
调用css(document.getElementById('elementId'))
将返回一个数组,每个CSS规则与传入的元素相匹配。 如果您想了解每个规则的更多具体信息,请查看CSSRule对象文档。
似乎我在经过一个小时的研究之后才设法回答我自己的问题。
这很简单:
window.getMatchedCSSRules(document.getElementById("description"))
(在WebKit / Chrome中工作,也可能是其他的)
看看这个图书馆,这是所要求的: http : //www.brothercake.com/site/resources/scripts/cssutilities/
它适用于所有现代浏览器,直接返回到IE6,可以给你像Firebug规则和属性集合(事实上它比Firebug更精确),也可以计算任何规则的相对或绝对特异性。 唯一需要注意的是,虽然它理解静态媒体types,但它不理解媒体查询。
简短的版本2017年4月12日
挑战者出现。
var getMatchedCSSRules = (el, css = el.ownerDocument.styleSheets) => [].concat(...[...css].map(s => [...s.cssRules||[]])) /* 1 */ .filter(r => el.matches(r.selectorText)); /* 2 */
Line /* 1 */
构build一个所有规则的平面arrays。
行/* 2 */
丢弃不匹配的规则。
根据@SB在同一页上的函数css(el)
。
例1
var div = iframedoc.querySelector("#myelement"); var rules = getMatchedCSSRules(div, iframedoc.styleSheets); console.log(rules[0].parentStyleSheet.ownerNode, rules[0].cssText);
例2
var getMatchedCSSRules = (el, css = el.ownerDocument.styleSheets) => [].concat(...[...css].map(s => [...s.cssRules||[]])) .filter(r => el.matches(r.selectorText)); function Go(big,show) { var r = getMatchedCSSRules(big); PrintInfo: var f = (dd,rr,ee="\n") => dd + rr.cssText.slice(0,50) + ee; show.value += "--------------- Rules: ----------------\n"; show.value += f("Rule 1: ", r[0]); show.value += f("Rule 2: ", r[1]); show.value += f("Inline: ", big.style); show.value += f("Computed: ", getComputedStyle(big), "(…)\n"); show.value += "-------- Style element (HTML): --------\n"; show.value += r[0].parentStyleSheet.ownerNode.outerHTML; } Go(...document.querySelectorAll("#big,#show"));
.red {color: red;} #big {font-size: 20px;}
<h3 id="big" class="red" style="margin: 0">Lorem ipsum</h3> <textarea id="show" cols="70" rows="10"></textarea>
这是一个SB的答案版本,它也返回匹配媒体查询中的匹配规则。 我已经删除了*.rules || *.cssRules
*.rules || *.cssRules
合并和.matches
实现查找器; 添加一个polyfill或添加这些行,如果你需要它们。
该版本还返回CSSStyleRule
对象而不是规则文本。 我认为这样更有用一些,因为规则的细节可以通过编程的方式更容易地被探测到。
咖啡:
getMatchedCSSRules = (element) -> sheets = document.styleSheets matching = [] loopRules = (rules) -> for rule in rules if rule instanceof CSSMediaRule if window.matchMedia(rule.conditionText).matches loopRules rule.cssRules else if rule instanceof CSSStyleRule if element.matches rule.selectorText matching.push rule return loopRules sheet.cssRules for sheet in sheets return matching
JS:
function getMatchedCSSRules(element) { var i, len, matching = [], sheets = document.styleSheets; function loopRules(rules) { var i, len, rule; for (i = 0, len = rules.length; i < len; i++) { rule = rules[i]; if (rule instanceof CSSMediaRule) { if (window.matchMedia(rule.conditionText).matches) { loopRules(rule.cssRules); } } else if (rule instanceof CSSStyleRule) { if (element.matches(rule.selectorText)) { matching.push(rule); } } } }; for (i = 0, len = sheets.length; i < len; i++) { loopRules(sheets[i].cssRules); } return matching; }
var GetMatchedCSSRules = (elem, css = document.styleSheets) => Array.from(css) .map(s => Array.from(s.cssRules).filter(r => elem.matches(r.selectorText))) .reduce((a,b) => a.concat(b)); function Go(paragraph, print) { var rules = GetMatchedCSSRules(paragraph); PrintInfo: print.value += "Rule 1: " + rules[0].cssText + "\n"; print.value += "Rule 2: " + rules[1].cssText + "\n\n"; print.value += rules[0].parentStyleSheet.ownerNode.outerHTML; } Go(document.getElementById("description"), document.getElementById("print"));
p {color: red;} #description {font-size: 20px;}
<p id="description">Lorem ipsum</p> <textarea id="print" cols="50" rows="12"></textarea>
确保IE9 +,我写了一个函数,计算所请求的元素及其子元素的CSS,并在下面的代码片段中提供将其保存到新的类名称的可能性。
/** * @function getElementStyles * * Computes all CSS for requested HTMLElement and its child nodes and applies to dummy class * * @param {HTMLElement} element * @param {string} className (optional) * @param {string} extras (optional) * @return {string} CSS Styles */ function getElementStyles(element, className, addOnCSS) { if (element.nodeType !== 1) { return; } var styles = ''; var children = element.getElementsByTagName('*'); className = className || '.' + element.className.replace(/^| /g, '.'); addOnCSS = addOnCSS || ''; styles += className + '{' + (window.getComputedStyle(element, null).cssText + addOnCSS) + '}'; for (var j = 0; j < children.length; j++) { if (children[j].className) { var childClassName = '.' + children[j].className.replace(/^| /g, '.'); styles += ' ' + className + '>' + childClassName + '{' + window.getComputedStyle(children[j], null).cssText + '}'; } } return styles; }
用法
getElementStyles(document.getElementByClassName('.my-class'), '.dummy-class', 'width:100%;opaity:0.5;transform:scale(1.5);');