Reputation:
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
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
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