Reputation: 12747
I have paragraphs of text that might be like this:
<p>
<span style='font-family:arial'>
Some text
</span>
</p>
or
<p>
<strong>
Some more text
<strong>
</p>
or
<p>
<strong>
<em>
Yet more text
</em>
</strong>
</p>
However many nested tags there are, I'm able to get just the text, simply using $('p').text()
. The problem is when <br>
pops up in the middle. In that case, whatever tag the text is in gets broken up. So for example, this:
<p>
<strong>
Some more text
</strong>
</p>
will turn into this:
<p>
<strong>
Some
</strong>
<br />
<strong>
more text
</strong>
</p>
So you see, there are now 2 text nodes in the <strong>
tag, not just one. What I want to do is to get just the text with it's original parent tags, with <br>
treated as just another text node, but without <br>
-induced-tag-split-up intrusion. For example, given the 2-node HTML above, I just want a function that returns this:
<p>
<strong>
Some
<br />
more text
</strong>
</p>
That would be fine for a few given formats, but there could different types of HTML nesting that I need to retain (such as <p><strong><em>
or <p><em><strong>
or <p><strong><span>
and so on.
Rather than getting lost in loops, I suppose the easiest way is to get the $('p').html()
and simply chop away all tags around <br>
? On the left there of <br>
would be closing tags, on the right there would be opening tags. Would there be regex solution for this then?
Upvotes: 0
Views: 295
Reputation: 338416
<br>
within a <p>
<br>
elements, compare the names of the immediately preceding and following elements<br>
and the contents of the following element into the preceding elementThis:
$("p").clone().find("br").each(function() {
var $this = $(this), $prev = $this.prev(), $next = $this.next();
if ( $prev.length && $prev.prop("nodeName") === $next.prop("nodeName") ) {
$prev.append( $this, $next.contents() );
$next.remove();
}
}).end().each(function () {
console.log( $(this).html() );
});
(Note that I use clone()
to avoid modifying the original.)
When applied to
<p>
<strong>
Some
</strong>
<br />
<strong>
more text
</strong>
</p>
writes this to the console
<strong>
Some
<br>
more text
</strong>
http://jsfiddle.net/Tomalak/y3hSp/
Here is an iterative approach that collapses adjacent nodes that are separated by <br>
, in form of a jQuery plugin:
$.fn.extend({
collapseBreaks: function () {
return this.each(function () {
var done = false;
while (!done) {
done = true;
$(this).find("br").each(function() {
var $this = $(this),
$prev = $this.prev(),
$next = $this.next();
if (
$prev.length
&& $prev.prop("nodeName") === $next.prop("nodeName")
) {
$prev.append( $this, $next.contents() );
$next.remove();
done = false;
}
});
}
});
}
});
Use as
$("p").collapseBreaks();
http://jsfiddle.net/Tomalak/FJFgk/3/
Upvotes: 2
Reputation: 7517
So, what about:
var innerString = thatPFromYourQuestion.innerHTML;
innerString = innerString.replace("<.*>", "");
That should replace every tag with an empty string, returning all the text inside.
I think I misunderstood your question. If you just want literally what is in that paragraph, .innerHTML
will do exactly that. If you want the <BR />
chopped of, you should use a slightly different version of that replace()
call:
innerString = innerString.replace("<br>", "");
Upvotes: 1