user3758078
user3758078

Reputation:

jQuery: If element is empty excluding whitespace and comments

The following code checks if an element has no content within it(not including whitespace or line breaks). In addition to it ignoring whitespace, I would also like it to ignore comments or anything that isn't an HTML tag if possible. How can I achieve this?

        if( $.trim( $("#element").html() ) == '' ) {
            // do something if empty
        }

Upvotes: 3

Views: 3775

Answers (2)

Rick Hitchcock
Rick Hitchcock

Reputation: 35670

Based on your comment:

I want to check if the element contains any nodes, but not comments and whitespace.

To determine if an element contains nodes excluding comments, use .children().

To determine if an element contains text content excluding whitespace, use $.trim() with .text().

Combining these, your code becomes:

if($('#element').children().length>0 && $.trim($("#element").text())!=='')

Because non-zero numbers are truthy and empty strings are falsy, this can be shortened to:

if($('#element').children().length && !$.trim($("#element").text()))

In the example below, element2 is the only element that matches the criteria (non-comment nodes with whitespace only):

function test(el) {
  if($(el).children().length &&  !$.trim($(el).text())) {
    return 'Success - children with no visible text';
  }
  else {
    return 'Failure - '+
           $(el).children().length+' children -'+
           $(el).text();
  }
}

$('body').append('<p>element1: '+test('#element1')+'</p>');

$('body').append('<p>element2: '+test('#element2')+'</p>');

$('body').append('<p>element3: '+test('#element3')+'</p>');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="element1">
  Lorem ipsum
  <span>dolor</span>
  <!-- nothing to see here -->
  <strong>sit <em>amet</em></strong>
</div>

<div id="element2">
  <span> </span>
  <!-- nothing to see here -->
  <strong> <em> </em></strong>
</div>

<div id="element3">
  <!-- nothing to see here -->
</div>
<hr>

It may be informative to see how .children() differs from .contents(), which does include comment nodes as well as text nodes:

constants='|element|attribute|text|cdata section|entity reference|entity|processing instruction|comment|document|document type|document fragment|notation'.split('|');

$('#info').children().each(function() {
  var t= $(this)[0];
  $('#children').append(
    '<tr><td>'+(t.tagName || '')+
        '<td>'+constants[t.nodeType]+
        '<td>'+(t.textContent.trim() || '<em>whitespace</em>')
  );
})

$('#info').contents().each(function() {
  var t= $(this)[0];
  $('#contents').append(
    '<tr><td>'+(t.tagName || '')+
        '<td>'+constants[t.nodeType]+
        '<td>'+(t.textContent.trim() || '<em>whitespace</em>')
  );
})
body, table {
  font: 12px verdana;
}

table {
  border: 1px solid #666;
  border-collapse: collapse;
}

td, th {
  border-right: 1px solid #ddd;
  border-bottom: 1px solid #bbb;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="info">
  Lorem ipsum
  <span>dolor</span>
  <!-- nothing to see here -->
  <strong>sit <em>amet</em></strong>
</div>
<hr>
<strong>.children():</strong>
<table id="children">
  <tr><th>Tag<th>Node type<th>Text content
</table>
<hr>
<strong>.contents():</strong>
<table id="contents">
  <tr><th>Tag<th>Node type<th>Text content
</table>

Upvotes: 7

Alexander Dayan
Alexander Dayan

Reputation: 2924

You can use the textContent property of the element.

The textContent property sets or returns the textual content of the specified node, and all its descendants. Comments, however, are not counted since it's not HTML tag.

See the sample code:

$(document).ready(function(){
  alert("DIV1: " + $.trim( $("#div1").text()) );
  alert("DIV2:" + $.trim( $("#div2").text()) );
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="div1"> <!-- this div contains a comment --> </div>
<div id="div2">This div has <b>SOMETHING</b> inside</div>

Upvotes: 0

Related Questions