I'm looking for some ideas for the most efficient way to remove trailing html <br/> tags using javascript or jquery.
RULES:
- The br, at the front and end must be removed.
- It must remove non-closing and self-closing br tags.
- All br within the textual content must remain untouched.
THE HTML:
<div class="generatedContent">
<br>My awesome content.
<br><br>Some More awesome content.
<br>
<br>
<br>I still need the content written here<br/>
<br>
<br>
<br>
<br>
<br>
<br>
</div>
THE DESIRED OUTPUT:
<div class="generatedContent">
My awesome content.
<br><br>Some More awesome content.
<br>
<br>
<br>I still need the content written here
</div>
I'm looking for some ideas for the most efficient way to remove trailing html <br/> tags using javascript or jquery.
RULES:
- The br, at the front and end must be removed.
- It must remove non-closing and self-closing br tags.
- All br within the textual content must remain untouched.
THE HTML:
<div class="generatedContent">
<br>My awesome content.
<br><br>Some More awesome content.
<br>
<br>
<br>I still need the content written here<br/>
<br>
<br>
<br>
<br>
<br>
<br>
</div>
THE DESIRED OUTPUT:
<div class="generatedContent">
My awesome content.
<br><br>Some More awesome content.
<br>
<br>
<br>I still need the content written here
</div>
Share
Improve this question
edited Jan 21, 2010 at 17:59
Andrew
asked Jan 21, 2010 at 17:33
AndrewAndrew
3,5705 gold badges39 silver badges51 bronze badges
2
- 1 I don't see how your desired output matches your rules – hunter Commented Jan 21, 2010 at 17:57
- @ Hunter, I believe you are talking about Rule #1, I updated it and moved it to Rule #3, which I believe makes more grammatical sense. – Andrew Commented Jan 21, 2010 at 18:00
5 Answers
Reset to default 5Can't understand why you'd want to to use regular expressions for this, as most answers are. Using DOM methods is easy here:
function isBrOrWhitespace(node) {
return node && ( (node.nodeType == 1 && node.nodeName.toLowerCase() == "br") ||
(node.nodeType == 3 && /^\s*$/.test(node.nodeValue) ) );
}
function trimBrs(node) {
while ( isBrOrWhitespace(node.firstChild) ) {
node.removeChild(node.firstChild);
}
while ( isBrOrWhitespace(node.lastChild) ) {
node.removeChild(node.lastChild);
}
}
$(".generatedContent").each( function() {
trimBrs(this);
} );
Try this:
var everything = $('.generatedContent').contents();
for(var i=everything.length-1;i>0;i--)
{
if((everything.get(i).tagName == 'BR'
&& everything.get(i-1).tagName == 'BR')
|| (everything.get(i).textContent.match(/\w/)==null))
$(everything.get(i)).remove();
else
break;
}
It seems to work in FF and IE7, that I've tried.
Could probably be improved but it should work:
$('.generatedContent').each(function() {
var str = $(this).html();
var regex1 = /^([\n ]*)(<br.*?>)*/;
var regex2 = /(<br.*?>)*([\n ]*)$/;
str = str.replace(regex1,'');
str = str.replace(regex2,'');
$(this).html(str);
})
Pretty simple. Take the HTML of the generatedContent div then apply the following regex:
s = s.replace(/^(\s*<br\s*\/?>)*\s*|\s*(<br\s*\/?>\s*)*$/g, '')
There's probably a more efficient way to do it using pure JS, but this is probably more succint.
Here is a non regex solution that works for me in Firefox. Could probably use some better edge case handling but the idea works. Basically it just finds the first and last non-empty text nodes and removes all nodes before and after.
var firstValidTextNode = -1;
var lastValidTextNode = -1;
$('.generatedContent').contents().each(function(index){
if (this.nodeType != 1 && $.trim($(this).text()).length) {
if (firstValidTextNode == -1) firstValidTextNode = index;
lastValidTextNode = index;
}
});
if (lastValidTextNode != -1 && firstValidTextNode != -1)
$('.generatedContent').contents().slice(0, firstValidTextNode).remove().end().slice(lastValidTextNode + 1).remove();