Viele Tools / APIs bieten Möglichkeiten zur Auswahl von Elementen bestimmter Klassen oder IDs. Es ist auch möglich, die vom Browser geladenen Roh-Stylesheets zu überprüfen.
Damit Browser ein Element rendern können, kompilieren sie jedoch alle CSS-Regeln (möglicherweise aus verschiedenen Stylesheet-Dateien) und wenden sie auf das Element an. Dies sehen Sie mit Firebug oder dem WebKit Inspector - dem vollständigen CSS-Vererbungsbaum für ein Element.
Wie kann ich diese Funktion in reinem JavaScript reproduzieren, ohne zusätzliche Browser-Plugins zu benötigen?
Vielleicht kann ein Beispiel klarstellen, wonach ich suche:
<style type="text/css">
p { color :red; }
#description { font-size: 20px; }
</style>
<p id="description">Lorem ipsum</p>
Hier werden auf das p # -Beschreibungselement zwei CSS-Regeln angewendet: eine rote Farbe und eine Schriftgröße von 20 px.
Ich möchte die Quelle finden, aus der diese berechneten CSS-Regeln stammen (Farbe kommt die p-Regel und so weiter).
quelle
Antworten:
Da diese Frage derzeit keine einfache (nicht bibliotheksbezogene) browserübergreifende Antwort enthält, werde ich versuchen, eine bereitzustellen:
JSFiddle: http://jsfiddle.net/HP326/6/
Beim Aufruf
css(document.getElementById('elementId'))
wird ein Array mit einem Element für jede CSS-Regel zurückgegeben, die dem übergebenen Element entspricht. Wenn Sie genauere Informationen zu den einzelnen Regeln erhalten möchten, lesen Sie die Dokumentation zum CSSRule-Objekt .quelle
a.matches
ist in dieser Zeile definiert :a.matches = a.matches || a.webkitMatchesSelector || a.mozMatchesSelector || a.msMatchesSelector || a.oMatchesSelector
. Wenn es bereits eine (Standard-) "Übereinstimmungs" -Methode für DOM-Knoten gibt, wird diese verwendet. Andernfalls wird versucht, die Webkit-spezifische Methode (webkitMatchesSelector) und dann die Mozilla-, Microsoft- und Opera-Methode zu verwenden. Sie können mehr darüber hier lesen: developer.mozilla.org/en/docs/Web/API/Element/matchesif (a.matches(rules[r].selectorText))
.css()
jedes der übergeordneten Elemente aufrufen .BEARBEITEN: Diese Antwort ist jetzt veraltet und funktioniert in Chrome 64+ nicht mehr . Auf dem Weg zum historischen Kontext. Tatsächlich verweist dieser Fehlerbericht auf diese Frage, um alternative Lösungen zu finden.
Scheint, als hätte ich es geschafft, meine eigene Frage nach einer weiteren Stunde Recherche zu beantworten.
So einfach ist das:
(Funktioniert in WebKit / Chrome, möglicherweise auch in anderen)
quelle
Schauen Sie sich diese Bibliothek an, die genau das tut, wonach Sie gefragt wurden: http://www.brothercake.com/site/resources/scripts/cssutilities/
Es funktioniert in allen modernen Browsern bis hin zu IE6, bietet Ihnen Regel- und Eigenschaftssammlungen wie Firebug (tatsächlich ist es genauer als Firebug) und kann auch die relative oder absolute Spezifität einer Regel berechnen. Die einzige Einschränkung ist, dass es zwar statische Medientypen versteht, Medienabfragen jedoch nicht versteht.
quelle
Kurzfassung 12. April 2017
Herausforderer erscheint.
Line erstellt
/* 1 */
ein flaches Array aller Regeln.Linie
/* 2 */
verwirft nicht übereinstimmende Regeln.Basierend auf der Funktion
css(el)
von @SB auf derselben Seite.Beispiel 1
Beispiel 2
Mängel
@import
,@media
.Vielleicht werde ich eines Tages auf diese Mängel eingehen.
Langfassung 12. August 2018
Hier ist eine viel umfassendere Implementierung, die von einer GitHub-Seite einer anderen Person stammt (aus diesem Originalcode über Bugzilla gespalten ). Geschrieben für Gecko und IE, soll aber auch mit Blink funktionieren.
4. Mai 2017: Der Spezifitätsrechner hatte kritische Fehler, die ich jetzt behoben habe. (Ich kann die Autoren nicht benachrichtigen, da ich keinen GitHub-Account habe.)
12. August 2018: Die letzten Chrome-Updates scheinen den Objektbereich (
this
) von Methoden entkoppelt zu haben , die unabhängigen Variablen zugewiesen wurden. Dahermatcher(selector)
funktioniert der Aufruf nicht mehr. Das Ersetzen durchmatcher.call(el, selector)
hat es gelöst.Behobene Fehler
= match
→+= match
return re ? re.length : 0;
→return matches ? matches.length : 0;
_matchesSelector(element, selector)
→matchesSelector(element, selector)
matcher(selector)
→matcher.call(el, selector)
quelle
Hier ist eine Version der Antwort von SB, die auch übereinstimmende Regeln in übereinstimmenden Medienabfragen zurückgibt. Ich habe die
*.rules || *.cssRules
Koaleszenz und den.matches
Implementierungsfinder entfernt. Fügen Sie eine Polyfüllung hinzu oder fügen Sie diese Zeilen wieder hinzu, wenn Sie sie benötigen.Diese Version gibt auch die zurück
CSSStyleRule
Objekte anstelle des Regeltextes zurück. Ich denke, dies ist etwas nützlicher, da die Besonderheiten der Regeln auf diese Weise leichter programmgesteuert überprüft werden können.Kaffee:
JS:
quelle
element
anzuwenden?cloneNode(true)
Funktionalität zu schaffen , aber mit tief geklontem Styling.Hier ist meine Version der
getMatchedCSSRules
Funktion, die@media
Abfrage unterstützt.quelle
quelle
Um IE9 + zu gewährleisten, habe ich eine Funktion geschrieben, die CSS für das angeforderte Element und seine untergeordneten Elemente berechnet und die Möglichkeit bietet, es bei Bedarf im folgenden Snippet unter einem neuen Klassennamen zu speichern.
Verwendung
quelle
computeStyles
Unterprogramm durch einfach ersetzenel => getComputedStyle(el).cssText
. Beweis: Geige . 2.'.' + element.className
ist eine fehlerhafte Konstruktion, da davon ausgegangen wird, dass ein Klassenname vorhanden ist. Gültige Konstruktion istelement.className.replace(/^| /g, '.')
. 3. Ihre Funktion ignoriert die Möglichkeit anderer CSS-Selektoren als nur Klassen. 4. Ihre Rekursion ist willkürlich auf eine Ebene beschränkt (Kinder, aber keine Enkelkinder). 5. Verwendung: es keinegetElementByClassName
, nurgetElementsByClassName
(gibt einen Array).Ich denke, die Antwort von SB sollte zu diesem Zeitpunkt die akzeptierte sein, aber sie ist nicht genau. Es wird einige Male erwähnt, dass es einige Regeln geben wird, die möglicherweise übersehen werden. Vor diesem Hintergrund habe ich mich entschieden, document.querySelectorAll anstelle von element.matches zu verwenden. Das einzige ist, dass Sie eine eindeutige Identifizierung von Elementen benötigen, um sie mit der gesuchten zu vergleichen. In den meisten Fällen denke ich, dass dies erreichbar ist, indem die ID auf einen eindeutigen Wert festgelegt wird. Auf diese Weise können Sie das übereinstimmende Element identifizieren, das Ihnen gehört. Wenn Sie sich eine allgemeine Möglichkeit vorstellen können, das Ergebnis von document.querySelectorAll mit dem gesuchten Element abzugleichen, wäre dies im Wesentlichen eine vollständige Polyfüllung von getMatchedCSSRules.
Ich habe die Leistung für document.querySelectorAll überprüft, da es wahrscheinlich langsamer als element.matches ist, aber in den meisten Fällen sollte es kein Problem sein. Ich sehe, dass es ungefähr 0,001 Millisekunden dauert.
Ich habe auch eine CSSUtilities-Bibliothek gefunden, die ankündigt, dass dies möglich ist, aber ich fühle mich alt und wurde seit einiger Zeit nicht mehr aktualisiert. Wenn ich mir den Quellcode anschaue, denke ich, dass es Fälle gibt, in denen er fehlt.
quelle