0

I have this:

<p>
<br>
<br>
JQuery problems again...
<br>
<br>
Why me...?
</p>

I tried using this:

$("p").children(":first-child").nextUntil(":not(br)").remove();

But I somehow end up with this:

<p>
JQuery problems again...Why me...?
</p>

To my understanding, do correct me if I'm wrong, the code searches for the first-child of <p>, which would be the first <br>, then deletes all of them that appears before the text.

All I want to do is delete the first <br>s that appear before the text in a <p> element. Can you please tell me how I can do that?

c0deNinja
  • 3,956
  • 1
  • 29
  • 45
user969591
  • 23
  • 6

4 Answers4

1

CSS selectors can never match text per se—only elements. jQuery doesn’t have that much support for matching text nodes. I guess you’d have to do something like this:

$("p").each(function () {
  $($(this).contents()).each(function () {
    if (this.nodeType === 3 && /\S/.test($(this).text())) {
      // Found some text, so stop removing elements.
      return false
    } else if ($(this).is("br")) {
      $(this).remove()
    }
  })
})
Daniel Brockman
  • 18,826
  • 3
  • 29
  • 40
1

If you change your HTML to this where the text is in a span:

<p>
    <br>
    <br>
    <span>JQuery problems again...</span>
    <br>
    <br>
    <span>Why me...?</span>
</p>

You can then use this jQuery to remove those leading
tags:

$("p br:first-child").nextUntil(":not(br)").andSelf().remove();

See it work here: http://jsfiddle.net/jfriend00/W2W5F/

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • It is on Blogger, and I can't add `span`s to comments manually. – user969591 Oct 05 '11 at 00:51
  • Then, you're stuck with searching for text nodes manually like in Daniel's example. I was just offering something different if you had control of the HTML. – jfriend00 Oct 05 '11 at 00:53
0

I know it's a quite old question, but I found this topic when I faced a similar problem today.

I've just found an alternate - and simple - solution, maybe it will be useful for someone:

$('p').each(function(){
    var h = $(this).html().trim();

    // remove <br> tags before text
    while (h.match(/^<br ?\/?>/gi)) h = h.replace(/^<br ?\/?>/gi, '').trim();

    // remove <br> tags after text
    while (h.match(/<br ?\/?>$/gi)) h = h.replace(/<br ?\/?>$/gi, '').trim();

    $(this).html(h);    
});

JSFiddle demo: http://jsfiddle.net/ULwCL/

juzraai
  • 5,693
  • 8
  • 33
  • 47
0

It looks like jQuery doesn't help a whole lot here so rather than try to force it in, this looks like it's a job for plain javascript (other than identifying the p tags). This will work on your existing HTML without adding <span> tags around the text.

$("p").each(function() {
    var children = this.childNodes;
    var removals = [], child, i;
    for (i = 0; i < children.length; i++) {
        child = children[i];
        // nodeType 1 is ELEMENT_NODE
        if (child.nodeType == 1) {
            if (child.nodeName.toLowerCase() == "br") {
                removals.push(child);
            }
        }
        // nodeType 3 is TEXT_NODE
        else if (child.nodeType == 3) {
            // stop at first non whitespace text node
            if (child.nodeValue.match(/\S/)) {
                break;
            }
        }
    }
    // now remove the nodes we collected for removal
    // remove outside the first loop because childNodes is a live array
    // and we don't want it changing while iterating it
    for (i = 0; i < removals.length; i++) {
        removals[i].parentNode.removeChild(removals[i]);
    }
});

You can see it work here: http://jsfiddle.net/jfriend00/NjaRF/

jfriend00
  • 683,504
  • 96
  • 985
  • 979