JQuery: I'm trying to delete the first <br> before the text, but every <br> gets deleted
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?
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()
}
})
})
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/
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/
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/
精彩评论