Kısa versiyon 12 Nisan 2017
Challenger belirir.
var getMatchedCSSRules = (el, css = el.ownerDocument.styleSheets) =>
[].concat(...[...css].map(s => [...s.cssRules||[]]))
.filter(r => el.matches(r.selectorText));
Çizgi /* 1 */, tüm kuralların düz bir dizisini oluşturur.
Satır, /* 2 */eşleşmeyen kuralları iptal eder.
Dayanarak işlevicss(el) aynı sayfada @SB tarafından.
örnek 1
var div = iframedoc.querySelector("#myelement");
var rules = getMatchedCSSRules(div, iframedoc.styleSheets);
console.log(rules[0].parentStyleSheet.ownerNode, rules[0].cssText);
Örnek 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>
Eksiklikler
- Hiçbir medya işleme, hayır
@import, @media.
- Etki alanları arası stil sayfalarından yüklenen stillere erişim yok.
- Seçici "özgüllük" e göre sıralama yok (önem sırası).
- Ebeveynlerden miras kalan stil yok.
- Eski veya ilkel tarayıcılarla çalışmayabilir.
- Sözde sınıflarla ve sözde seçicilerle nasıl başa çıktığından emin değilim, ancak iyi görünüyor.
Belki bir gün bu eksiklikleri gideririm.
Uzun versiyon 12 Ağustos 2018
İşte birinin GitHub sayfasından alınan çok daha kapsamlı bir uygulama
( Bugzilla aracılığıyla bu orijinal koddan çatallanmıştır ). Gecko ve IE için yazılmış, ancak Blink ile de çalıştığı söyleniyor.
4 Mayıs 2017: Özgüllük hesaplayıcısında şimdi düzelttiğim kritik hatalar var. (Yazarlara bilgi veremiyorum çünkü GitHub hesabım yok.)
12 Ağustos 2018: Son Chrome güncellemeleri, nesne kapsamını ( this) bağımsız değişkenlere atanan yöntemlerden ayırmış görünüyor . Bu nedenle çağrı matcher(selector)çalışmayı durdurdu. Değiştirmek matcher.call(el, selector)sorunu çözdü.
if (typeof window.getMatchedCSSRules !== 'function') {
var ELEMENT_RE = /[\w-]+/g,
ID_RE = /#[\w-]+/g,
CLASS_RE = /\.[\w-]+/g,
ATTR_RE = /\[[^\]]+\]/g,
PSEUDO_CLASSES_RE = /\:(?!not)[\w-]+(\(.*\))?/g,
PSEUDO_ELEMENTS_RE = /\:\:?(after|before|first-letter|first-line|selection)/g;
function toArray(list) {
return [].slice.call(list);
}
function getSheetRules(stylesheet) {
var sheet_media = stylesheet.media && stylesheet.media.mediaText;
if ( stylesheet.disabled ) return [];
if ( sheet_media && sheet_media.length && ! window.matchMedia(sheet_media).matches ) return [];
return toArray(stylesheet.cssRules);
}
function _find(string, re) {
var matches = string.match(re);
return matches ? matches.length : 0;
}
function calculateScore(selector) {
var score = [0,0,0],
parts = selector.split(' '),
part, match;
while (part = parts.shift(), typeof part == 'string') {
match = _find(part, PSEUDO_ELEMENTS_RE);
score[2] += match;
match && (part = part.replace(PSEUDO_ELEMENTS_RE, ''));
match = _find(part, PSEUDO_CLASSES_RE);
score[1] += match;
match && (part = part.replace(PSEUDO_CLASSES_RE, ''));
match = _find(part, ATTR_RE);
score[1] += match;
match && (part = part.replace(ATTR_RE, ''));
match = _find(part, ID_RE);
score[0] += match;
match && (part = part.replace(ID_RE, ''));
match = _find(part, CLASS_RE);
score[1] += match;
match && (part = part.replace(CLASS_RE, ''));
score[2] += _find(part, ELEMENT_RE);
}
return parseInt(score.join(''), 10);
}
function getSpecificityScore(element, selector_text) {
var selectors = selector_text.split(','),
selector, score, result = 0;
while (selector = selectors.shift()) {
if (matchesSelector(element, selector)) {
score = calculateScore(selector);
result = score > result ? score : result;
}
}
return result;
}
function sortBySpecificity(element, rules) {
function compareSpecificity (a, b) {
return getSpecificityScore(element, b.selectorText) - getSpecificityScore(element, a.selectorText);
}
return rules.sort(compareSpecificity);
}
function matchesSelector(el, selector) {
var matcher = el.matchesSelector || el.mozMatchesSelector ||
el.webkitMatchesSelector || el.oMatchesSelector || el.msMatchesSelector;
return matcher.call(el, selector);
}
window.getMatchedCSSRules = function (element ) {
var style_sheets, sheet, sheet_media,
rules, rule,
result = [];
style_sheets = toArray(window.document.styleSheets);
while (sheet = style_sheets.shift()) {
rules = getSheetRules(sheet);
while (rule = rules.shift()) {
if (rule.styleSheet) {
rules = getSheetRules(rule.styleSheet).concat(rules);
continue;
}
else if (rule.media) {
rules = getSheetRules(rule).concat(rules);
continue
}
if (matchesSelector(element, rule.selectorText)) {
result.push(rule);
}
}
}
return sortBySpecificity(element, result);
};
}
Sabit hatalar
= match → += match
return re ? re.length : 0; → return matches ? matches.length : 0;
_matchesSelector(element, selector) → matchesSelector(element, selector)
matcher(selector) → matcher.call(el, selector)