最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Can you detect when a dom node's style is set to 'auto'? - Stack Overflow

programmeradmin0浏览0评论

With the example CSS:

.thing { height: auto }

and HTML:

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

is it possible to detect that the height of .thing is set to 'auto'?

The following methods return values:

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

Is there any method that will tell me that the browser is calculating these values from 'auto'?

With the example CSS:

.thing { height: auto }

and HTML:

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

is it possible to detect that the height of .thing is set to 'auto'?

The following methods return values:

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

Is there any method that will tell me that the browser is calculating these values from 'auto'?

Share Improve this question edited Dec 25, 2011 at 1:08 BoltClock 725k165 gold badges1.4k silver badges1.4k bronze badges asked May 20, 2011 at 12:53 stephbandstephband 2,6432 gold badges27 silver badges35 bronze badges 2
  • This is probably a valid question on its own, but is there a deeper problem you're trying to solve? – quasistoic Commented May 20, 2011 at 18:32
  • Yes. Extending the behaviour of CSS3 transitions on the fly to be able to transition from { height: 20px } to { height: auto }, which no browser can currently do. – stephband Commented May 21, 2011 at 2:03
Add a ment  | 

4 Answers 4

Reset to default 3

Yes there is a way, but it's not a funny one. What you have to do is:

  1. Loop through all styletags and linked stylesheets.
  2. Then get the selectorText for all cssRules in all style tags

    styletag.sheet.cssRules.selectorText
    

    or for IE < 9

    styletag.styleSheet.cssRules.selectorText
    
  3. Get all of your elements parents id, class and tagName to find out what possible ways for the tag to get the attribute.

  4. Find all possible binations that point towards your element in your list of cssRules
  5. check those cssRules at cssRules.style.width if it is auto.

or do it some reverse way and find all cssRules with style.width == 'auto'; either way its not something easy to get without a lot of code

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

hope it helps, otherwise you have alot of digging to do :)

For the second option where you see [0] means you have to loop as there may be different file names, etc etc...

full example :

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

PLEASE NOTE

You must escape those from cross domain.e.g. if you have included <link ....="...jquery..../ui.css" /> it will not work as this might be considered as security risk (cross domain)...

This isn't the most efficient solution, particularly for old IE versions, but it should work pretty well:

  1. Measure the height of your element
  2. Append some content to the element e.g. <div style="clear: left; height: 30px">Test</div>
  3. Test the new height, if it has changed your element has height auto
  4. Remove the content

Here's my implementation:

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

Notes:

  • The 'quick check' line might not work correctly if there is a height: auto !important; rule in the CSS, in which case you'd always have to go the long route.
  • This is not efficient in terms of DOM interactions so your application would want to cache this result whenever possible.
  • I'm reluctant to cache the result internally in the plugin because classes/CSS rules might change and invalidate the result.
  • This won't work for elements with no body, such as <img> and <br>

Here's a more plete implementation of the above suggestions:

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

You'll need to implement asSpecific(a, b) which should work out if css selector a is at least as specific as selector b, e.g. p#foo a#bar is more specific than p.foo. You also need to take into account the !important flag.

This might be useful: http://www.w3/TR/CSS2/cascade.html#specificity

This should add a data property to each element specifying whether or not it has an auto height style in the CSS, but you'll also need to check the style attribute and think about default styles.

发布评论

评论列表(0)

  1. 暂无评论