Reputation: 731
I would like to remove the first occurrence of a tag e.g "p" tag that appears above an element, now this tag can either be directly above it (previous sibling) or it could be parent's previous sibling. I would like to do this in jQuery
<p>..</p>
<span>abcd</span>
<p>..</p>
<div>
<span>abcd</span>
in both the cases I would like to remove the p tag from span's perspective.
Upvotes: 0
Views: 118
Reputation: 150080
You can find an element's closest previous <p>
sibling using the .prevAll()
method together with .first()
. If the result is a non-empty jQuery object then you (obviously) have a match, so remove it.
If the result is an empty jQuery object then there wasn't a matching sibling, so try the same thing starting from the current span's parent, using a loop to keep going up the tree as far as needed.
(If you only want to test the element's immediate sibling then use .prev("p")
instead of prevAll("p").first()
.)
$("span").click(function() {
// not sure how you're getting a reference to the starting span element,
// but assuming for demonstration purposes it is 'this' in an event handler
var current = $(this);
var prev;
while (!current.is("body")) {
prev = current.prevAll("p").first();
if (prev.length > 0) {
prev.remove();
break;
}
current = current.parent();
}
});
div { border: thin black solid; margin: 2px; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<span>abcd</span>
<p>..</p>
<span>abcd</span>
<p>..</p>
<div>
<span>abcd</span>
</div>
<div>
<p>..</p>
<div>a div</div>
<span>abcd</span>
</div>
<p>..</p>
<div>
<div>
<div>
<div>
<span>abcd</span>
</div>
</div>
</div>
</div>
Upvotes: 1
Reputation: 1363
I understand you want to delete p
tag that is previous sibling of span
tag's parent where parent can be any levels above span
.
Check this script:
function isPTag($el) {
return $el.prop("tagName").toUpperCase() === 'P';
}
function removeIfPTag($el) {
if ($el.length > 0 && isPTag($el)) {
$el.remove();
return true;
}
return false;
}
function removeClosePTag($el) {
function removePrevious($el) {
var previous = $el.prevAll();
for (var j = 0; j < previous.length; j += 1) {
current = $(previous[j]);
if (removeIfPTag(current)) {
return true;
}
}
}
// Finds `p` in previous elements relative `span`
if (removePrevious($el)) {
return true;
}
var parents = $el.parents();
for (var i = 0; i < parents.length; i += 1) {
var current = $(parents[i]);
if (removeIfPTag(current)) {
return true;
}
// Finds `p` in previous elements relative to `current` (one of span's parents)
if (removePrevious(current)) {
return true;
}
}
return false;
}
console.log(removeClosePTag($('#first-span')));
console.log(removeClosePTag($('#second-span')));
console.log(removeClosePTag($('#third-span')));
console.log(removeClosePTag($('#fourth-span')));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<p>first p (should remain)</p>
<p>second p (should delete)</p>
<div>
<span id="first-span">first span</span>
</div>
</div>
<div>
<span id="second-span">second span</span>
<p>(should remain)</p>
</div>
<div>
<p>third p (should delete)</p>
<span id="third-span">first span</span>
</div>
<div>
<div>
<p>fourth p (should remain)</p>
</div>
<span id="fourth-span">fourth span</span>
</div>
Notice how fourth p is not removed even though it's above #fourth-span
. If you want to remove it then you would have to go through the entire DOM tree above initial span
element which would be expensive for CPU and might easily hang browser.
Upvotes: 0
Reputation: 564
I'm not sure if this demo is what you're looking for, but this maybe the case:
You will have to loop all p
tags and check if it has a next()
sibling and remove it and break the loop.
see this DEMO:
// loop all p's
$('p').each(function(ndx, elem) {
// if element has a next sibling
if ($(elem).next().length > 0) {
console.log('removed :', $(elem).text());
$(elem).remove(); // remove this <p> tag
return false; // break out of loop
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>first p of body</p>
<div class="container">
<p>first p of container div</p>
<span>abcd</span>
</div>
<p>second p of body</p>
<span>abcd</span>
<p>third p of body</p>
<div>
<span>abcd</span>
Upvotes: 0