1
\$\begingroup\$

I've made a simple function, this time in jQuery rather than JS, that just removes empty <p></p>, span and strong tags. I'm curious to see what everyone thinks about my solution as I'm relatively new to jQuery, and whether it could be improved. My original solution is as follows:

$('p').filter(function() {
 return ($(this).html().trim() == '&nbsp;');
}).remove();
$('span').filter(function() {
 return ($(this).html().trim() == '&nbsp;');
}).remove();
$('span').filter(function() {
 return ($(this).html().trim() == '');
}).remove();
$('strong').filter(function() {
 return ($(this).html().trim() == '');
}).remove();
$('p').filter(function() {
 return ($(this).html().trim() == '');
}).remove();

This isn't exactly dry... So I made a couple of other solutions:

/* MY DRIER SOLUTION 1 */
$.fn.jCleaner = function() {
    return $(this).filter(function() {
        return ($(this).text().trim() === '&nbsp;' || $(this).text().trim() === '');
        }).remove();
}
$('p, span, strong').jCleaner();

/* MY DRIER SOLUTION 2 */
function jCleaner() {
    return $(this).filter(function() {
        return ($(this).text().trim() == '&nbsp;' || $(this).text().trim() === '');
        }).remove();
}
$('p, span, strong').each(jCleaner);

And the original HTML is:

/* ORIGINAL HTML */
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id='test'>
    <p>text</p>
    <p>&nbsp;</p>
    <p>text</p>
    <p><span>text</span></p>
    <p><span></span></p>
    <p>text</p>
    <p><strong>text</strong></p>
    <p></p>
    <p>&nbsp;</p>
    <p>text</p>
    <p><span><strong>&nbsp;</strong></span></p>
    <p><span><strong>text</strong></span></p>
    <p>&nbsp;</p>
    <p><span>text</span></p>
    <p></p>
    <p><span></span></p>
    <p><span>&nbsp;</span></p>
    <p><span><strong></strong></span></p>
    <p>text</p>
</div>

So my questions are essentially how can my solutions be improved (if at all)? I had to write an entire function and then call it on each element. Thanks for any advice here.

Note: here's the solution in JS:

document.querySelectorAll("span, p, strong")
    .forEach(el => el.textContent.trim() === "" && el.parentNode.removeChild(el))
\$\endgroup\$
2
\$\begingroup\$

"This isn't exactly DRY" is pretty much what I think about

$(this).text().trim() == '&nbsp;' || $(this).text().trim() === ''

text() can be a very expensive call: I would refactor to only do $(this).text().trim() once.


As a minor concern, the use of trim() suggests that you want to remove nodes whose text is purely whitespace. So shouldn't a node whose text is &nsbp; &nbsp; be removed? Perhaps you should be using a regex match instead of trim()? Something like (warning: untested) $(this).text().match(/^(\s|&nbsp;)*$/).

And then you could take it further: &nbsp; isn't the only way of escaping U+00a0, and the other whitespace characters can also be escaped in various ways...

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.