你能检测到 dom 节点的样式何时设置为“auto”吗?

发布于 2024-11-09 00:47:03 字数 429 浏览 0 评论 0原文

通过示例 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”计算这些值?

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'?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

懷念過去 2024-11-16 00:47:03

是的,有一种方法,但它并不好笑。您需要做的是:

  1. 循环遍历所有 styletags 和链接的样式表。
  2. 然后获取所有样式标签中所有 cssRulesselectorText

    styletag.sheet.cssRules.selectorText
    

    或者对于 IE < 9

    styletag.styleSheet.cssRules.selectorText
    
  3. 获取所有元素的父元素 idclasstagName 以找出标签获取属性的可能方式。

  4. 找到所有可能的组合,指向你的元素
    cssRules 列表
  5. 检查 cssRules.style.width 处的 cssRules 如果它是自动的。

或者以相反的方式进行操作,找到所有带有 style.width == 'auto';cssRules ,无论哪种方式,如果没有大量代码,都不容易获得

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 combinations 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

々眼睛长脚气 2024-11-16 00:47:03
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 :)
        }
    }
}

请注意

如果您已包含,则必须从跨域中转义这些内容。
它将不起作用,因为这可能被视为安全风险(跨域)。 ..

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.com.../ui.css" /> it will not work as this might be considered as security risk (cross domain)...

顾忌 2024-11-16 00:47:03

这不是最有效的解决方案,特别是对于旧的 IE 版本,但它应该工作得很好:

  1. 测量元素的高度
  2. 向元素附加一些内容,例如
    Test

  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 规则可能会更改并使结果无效。
  • 这不适用于没有主体的元素,例如

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>
你的他你的她 2024-11-16 00:47:03

这是上述建议的更完整实现:

$("*").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#barp.foo更具体。您还需要考虑 !important 标志。

这可能有用: http://www.w3.org/TR/CSS2/ cascade.html#specificity

这应该向每个元素添加一个数据属性,指定它在 CSS 中是否具有自动高度样式,但您还需要检查样式属性并考虑默认样式。

Here's a more complete 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.org/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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文