Можете ли вы определить, когда стиль узла dom установлен на 'auto'? - PullRequest
14 голосов
/ 20 мая 2011

С примером CSS:

.thing { height: auto }

и HTML:

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

возможно ли определить, что высота .thing установлена ​​на 'auto'?

Следующие методы возвращают значения:

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

Есть ли какой-нибудь метод, который скажет мне, что браузер вычисляет эти значения из 'auto'?

Ответы [ 4 ]

3 голосов
/ 20 мая 2011

Да, есть способ, но он не смешной.Что вам нужно сделать, это:

  1. Перебрать все styletags и связанные таблицы стилей.
  2. Затем получите selectorText для всех cssRules во всех тегах стиля

    styletag.sheet.cssRules.selectorText
    

    или для IE <9 </p>

    styletag.styleSheet.cssRules.selectorText
    
  3. Получить все ваши элементы родителей id, class и tagName, чтобы узнать, чтовозможные способы получения атрибута тегом.

  4. Найдите все возможные комбинации, которые указывают на ваш элемент, в списке cssRules
  5. отметьте эти cssRules в cssRules.style.widthесли это авто.

или сделайте это каким-то обратным путем и найдите все cssRules с style.width == 'auto'; в любом случае, это не так легко получить без большого количества кода

1 голос
/ 20 мая 2011
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

надеюсь, это поможет, в противном случае вам придется много копаться:)

Для второго варианта, где вы видите [0] означает, что вы должны выполнить цикл, поскольку могут быть разные имена файлов и т. Д. И т. Д. *

полный пример:

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 :)
        }
    }
}

ПОЖАЛУЙСТА, ОБРАТИТЕ ВНИМАНИЕ

Вы должны избегать тех из кросс-домена.e.g. если вы включили <link ....="...jquery.com.../ui.css" /> это не будет работать, так как это может рассматриваться как угроза безопасности (междоменный) ...

0 голосов
/ 27 марта 2012

Вот более полная реализация приведенных выше предложений:

$("*").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);
            }
        });
    }
}

Вам нужно будет реализовать asSpecific(a, b), который должен сработать, если селектор css a по крайней мере так же специфичен, как селектор b, например. p#foo a#bar более конкретно, чем p.foo. Вам также необходимо учитывать флаг !important.

Это может быть полезно: http://www.w3.org/TR/CSS2/cascade.html#specificity

Это должно добавить свойство данных к каждому элементу, указывающее, имеет ли он стиль авто-высоты в CSS, но вам также необходимо проверить атрибут style и подумать о стилях по умолчанию.

0 голосов
/ 23 марта 2012

Это не самое эффективное решение, особенно для старых версий IE, но оно должно работать довольно хорошо:

  1. Измерьте высоту вашего элемента
  2. Добавьте некоторый контент кнапример, <div style="clear: left; height: 30px">Test</div>
  3. Проверьте новую высоту, если она изменилась, ваш элемент имеет высоту auto
  4. Удалите содержимое

Вот моя реализация:

$.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;
};

Примечания:

  • Строка 'быстрой проверки' может работать некорректно, если в CSS есть правило height: auto !important;, и в этом случае вам всегда придется идтидлинный маршрут.
  • Это неэффективно с точки зрения взаимодействия DOM, поэтому ваше приложение захочет кэшировать этот результат, когда это возможно.
  • Я неохотно кэширую результат внутри плагина, потому чтоПравила классов / CSS могут измениться и сделать результат недействительным.
  • Это не будет работать для элементов без тела, таких как <img> и <br>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...