snit80
snit80

Reputation: 731

Remove a tag in jQuery

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

Answers (3)

nnnnnn
nnnnnn

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

Linek
Linek

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

four
four

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

Related Questions