Frage Können Sie erkennen, ob der Stil eines Dom-Knotens auf 'auto' gesetzt ist?


Mit dem Beispiel-CSS:

.thing { height: auto }

und HTML:

<div class="thing">The quick brown fox jumps over a lazy dog.</div>

Ist es möglich zu erkennen, dass die Höhe von .thing auf 'auto' gesetzt ist?

Die folgenden Methoden geben Werte zurück:

jQuery('.thing').height()        // n
jQuery('.thing').css('height')   // 'npx'
getComputedStyle(node).height    // 'npx'

Gibt es eine Methode, die mir sagen wird, dass der Browser diese Werte von "Auto" berechnet?


14
2018-05-20 12:53


Ursprung


Antworten:


Ja, es gibt einen Weg, aber es ist kein lustiger. Was Sie tun müssen, ist:

  1. Schleife durch alle styletags und verknüpfte Stylesheets.
  2. Dann hol die selectorText für alle cssRules in allen Stil-Tags

    styletag.sheet.cssRules.selectorText
    

    oder für IE <9

    styletag.styleSheet.cssRules.selectorText
    
  3. Holen Sie sich alle Ihre Eltern Elemente id, class und tagName um herauszufinden, welche Möglichkeiten für das Tag, das Attribut zu erhalten.

  4. Finde alle möglichen Kombinationen, die auf dein Element in deinem zeigen Liste von cssRules
  5. prüfe diese cssRules beim cssRules.style.width wenn es automatisch ist.

oder mach es umgekehrt und finde alles cssRules mit style.width == 'auto'; So oder so ist es nicht einfach, ohne viel Code zu bekommen


3
2018-05-20 13:37



jQuery('.thing').each(function (i,n){
  console.log( $(n).style.height);// if not then just try to simply find the n.style.height
});

//this is another way // at least in ff it would work :)
window.document.styleSheets[0].cssRules[0].style.height

hoffe es hilft, sonst hast du viel zu tun :)

Für die zweite Option, wo Sie sehen [0] bedeutet, dass Sie eine Schleife machen müssen, da es verschiedene Dateinamen usw. geben kann ...

vollständiges Beispiel:

var ss = window.document.styleSheets;
for(i=0;i<ss.length;i++){
    var rules = ss[i].cssRules;
    for(j=0;j<rules.length;j++){//loop style sheets
        var rule = rules[j];
        if(rule.selectorText=='thing'){//loop each stylesheet rule
             console.log(rule.style.height);
              // should return height for everytime height is used with every .thing in any of your stylesheets attached :)
        }
    }
}

BITTE BEACHTEN SIE

Sie müssen die aus domain.e.g. wenn Sie eingeschlossen haben <link ....="...jquery.com.../ui.css" /> Es wird nicht funktionieren, da dies als Sicherheitsrisiko (domänenübergreifend) betrachtet werden könnte ...


1
2018-05-20 13:22



Dies ist nicht die effizienteste Lösung, besonders für alte IE-Versionen, aber es sollte ziemlich gut funktionieren:

  1. Messen Sie die Höhe Ihres Elements
  2. Füge etwas Inhalt dem Element hinzu, z.B. <div style="clear: left; height: 30px">Test</div>
  3. Testen Sie die neue Höhe, wenn es sich geändert hat, hat Ihr Element automatisch die Höhe
  4. Entfernen Sie den Inhalt

Hier ist meine Implementierung:

$.fn.hasAutoHeight = function() {
    if (this.length === 0) return;
    var self = this.first();
    var height = self.css("height");
    var position = self.css("position");

    // Check for inline elements
    if (self.css("display") === "inline" && self.css("float") === "none") {
        var position = self.css("position");
        if (position === "static" || position === "relative") return true;  
    }

    // Quick check to see if a style height is set
    if ($.style(self[0], "height") !== "") return false;

    // Otherwise use the long route
    var test = $('<div style="clear: both; height: 30px">Test</div>');
    self.append(test);
    var hasAutoHeight = self.css("height") !== height;
    test.css("color", "red").remove();
    return hasAutoHeight;
};

Anmerkungen:

  • Die Zeile 'Schnellprüfung' funktioniert möglicherweise nicht korrekt, wenn ein ' height: auto !important; Regel in der CSS, in diesem Fall müssten Sie immer die lange Route gehen.
  • Dies ist in Bezug auf DOM-Interaktionen nicht effizient, sodass Ihre Anwendung dieses Ergebnis nach Möglichkeit zwischenspeichern sollte.
  • Ich zögere, das Ergebnis intern im Plugin zwischenzuspeichern, da sich Klassen / CSS-Regeln ändern und das Ergebnis ungültig machen können.
  • Dies funktioniert nicht für Elemente ohne Körper, wie z <img> und <br>

0
2018-03-23 13:57



Hier ist eine vollständigere Implementierung der obigen Vorschläge:

$("*").data("autoHeight", "false");
var stylesheets = window.document.styleSheets;
for (i=0; i < stylesheets.length; i++) {
    var rules = stylesheets[i].cssRules;
    for (j = 0; j < rules.length; j++) {
        var rule = rules[j];
        var style = rule.style.getPropertyValue("height");
        var auto = !style || style.match(/^\s*auto\s*(!important)?$/);
        $(rule.selectorText).each(function() {
            var elem = $(this);
            if (asSpecific(rule.selectorText, $(elem).data("autoHeightSelector"))) {
                $(elem).data("autoHeight", !!auto);
                $(elem).data("autoHeightSelector", rule.selectorText);
            }
        });
    }
}

Sie müssen implementieren asSpecific(a, b) was sollte funktionieren, wenn css selector a ist mindestens so spezifisch wie Selektor b, z.B. p#foo a#bar ist spezifischer als p.foo. Sie müssen auch die berücksichtigen !important Flagge.

Dies könnte nützlich sein: http://www.w3.org/TR/CSS2/cascade.html#specificity

Dies sollte jedem Element eine Dateneigenschaft hinzufügen, die angibt, ob es einen automatischen Höhenstil im CSS hat oder nicht, aber Sie müssen auch das Stilattribut überprüfen und über Standardstile nachdenken.


0
2018-03-27 15:51