开发者

Check if element is empty of content, is a transparent container, blank

I need to check if an HTML element (any element will do) is empty of contents. By contents I don't mean text content or any other HTML elements, because that is already a given. I mean want to check if it's simply a blank element. For example:

Check if element is empty of content, is a transparent container, blank

If I hide the link, the only thing left is the paragraph element, which is now blank. It does not have any styles on it, so it's just a transparent 开发者_StackOverflow社区container with margin/padding/whatever, but no other visual styles. Is there a way to detect this in Javascript? Any weird browser quirk will do. Ugly solutions valid too.


You want to recursively walk the childNodes of your element and check them to see if they are all blank. The recursive walking logic isn't difficult. It really all depends on how you define a blank element:

Display: none
Or visibility: hidden
Or all off the following criteria are true:

  • Text
    • None
    • or only whitespace
    • or text color is transparent
    • or text color is the same as the parent's background color
  • Background
    • Transparent
    • Matches parent
  • Border
    • Style: none
    • or width 0px
    • or color transparent
    • or color matches parent background
  • Tag
    • Not <img />
  • Children
    • none
    • or all satisfy above criteria

So, your recursive function would look something like this:

if (!window.getComputedStyle)
{
    window.getComputedStyle = function(el)
    {
        return el.currentStyle || {};
    };
}
function isElementBlank(el)
{
    var style = window.getComputedStyle ? getComputedStyle(el, null) : el.currentStyle;
    if (style.display == "none" || style.visibility == "hidden")
    {
        return true;
    }
    if (el.tagName.toLowerCase() == "img")
    {
        return false;
    }
    var parentBG = "transparent";
    for (var parent = el.parentNode; parent; parent = parent.parentNode)
    {
        var parStyle = getComputedStyle(parent, null);
        if (parStyle.backgroundColor != "transparent")
        {
            parentBG = parStyle.backgroundColor;
            break;
        }
    }
    if (style.backgroundColor != "transparent" && style.backgroundColor != parentBG)
    {
        return false;
    }
    if (style.borderColor != "transparent" && 
        style.borderColor != parentBG && 
        parseInt(style.borderWidth) > 0 && 
        style.borderStyle != "none")
    {
        return false;
    }
    for (var i = 0; i < el.childNodes.length; i++)
    {
        var child = el.childNodes[i];
        if (child.nodeType == 3)
        {
            if (/\S/.test(child.nodeValue) && 
                style.color != parentBG && 
                style.color != "transparent")
            {
                return false;
            }
        }
        else if (!isElementBlank(child))
        {
            return false;
        }
    }
    return true;
}

I didn't test this, but it's a start at least.


You could use a method where you remove all HTML and then trim the result.

If the result is empty string then there are no visible text.

This would not detect a div with height and background-color though so of you need that kind of detection you would also need to go over the while subtree looking for elements with any visible css which would require a very verbose code.


To detect empty-of-content tags you can iterate all child nodes of every nodes and looking for not empty text nodes. If a not empty text node is found the test pass, otherwise the node is an empty of content one. I've done a test that seems to works fine in Firefox:

<div id="container">
<div>Text <span>buzz</span>
</div>
<p><a href="#">Hello</a>
</p>
</div>

<script>
var all = document.getElementsByTagName('body')[0].getElementsByTagName('*');


allNodes: for (var i = 0, l = all.length; i < l; i++) {

  // for each childNode of every node...
  for (var ii = 0, sub = all[i].childNodes, ll = sub.length; ii < ll; ii++) {

    // is it a text node?
    if (sub[ii].nodeType == 3) {
      // Is the text node NOT empty?
      if (/[^\s]+/.test(sub[ii].nodeValue)) {
        continue allNodes;
      }

    }

  }

  console.log(all[i], ' fails');

}
</script>

The test result is:

<div id="container"> fails
<p> fails
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜