skip to Main Content

My sample HTML markup is below. In each of the three nested sets of divs, I’m removing all <p> tags except for the first <p>.

But now I find I want to not remove all the <p> tags from just the first nested divs that have the anchor link a name="123"

How do I use an if statement and the name="123" attribute to exclude the first set of nested divs from having all their <p> tags removed?

Fiddle: https://jsfiddle.net/rbo6gtLd/

Edit 10/4/24

Thanks to Phil for his answer, but I want to use the format of my original function. But this updated jQuery doesn’t work:

$('.post-body').each(function() {
  const $this = $(this);
  if ($(this).find('a[name="123"]').length == 0) {
    $(this).find('p').not(":first").remove();
  }
}); 

This original jQuery doesn’t work:

$('.post-body').each(function() {
  const $this = $(this);
  if ($(this).closest('[name="123"]').length == 0) {
    $(this).find('p').not(":first").remove();
  }
});

HTML:

<div class="post">
  <a name="123"></a>
  <h3 class="post-title">Post</h3>
  <div class="NewPermalinkUrl">Text</div>
  <div class="post-body">
    <p>Content</p>
    <p>Content</p>  <!-- fix function so this isn't removed -->
    <p>Content</p>  <!-- fix function so this isn't removed -->
  </div>
</div>

<div class="post">
  <a name="456"></a>
  <h3 class="post-title">Post</h3>
  <div class="NewPermalinkUrl">Text</div>
  <div class="post-body">
    <p>Content</p>
    <p>Content</p>      <!-- this is currently removed -->
    <p>Content</p>      <!-- this is currently removed -->
  </div>
</div>

<div class="post">
  <a name="789"></a>
  <h3 class="post-title">Post</h3>
  <div class="NewPermalinkUrl">Text</div>
  <div class="post-body">
    <p>Content</p>
    <p>Content</p>     <!-- this is currently removed -->
    <p>Content</p>     <!-- this is currently removed -->
  </div>
</div>

2

Answers


  1. The problem is that .closest() travels hierarchically.

    You can use jQuery’s :not and :has selectors to exclude the .post element then search within that for the <p> tags you want to remove.

    You can also use the p:nth-child(n+2) selector to target every <p> tag after the first within each block.

    $('.post:not(:has(a[name="123"])) .post-body p:nth-child(n+2)').remove();
    

    However, you can achieve exactly the same thing purely with CSS which is objectively faster and prevents flash of unstyled content.

    .post { border: 1px solid; margin: 1rem 0; padding: 0.5rem; }
    .post-title { margin: 0 0 0.5rem; }
    .NewPermalinkUrl { color: blue; text-decoration: underline; }
    
    .post:not(:has(a[name="123"])) .post-body p:nth-child(n+2) {
      /* display: none; */
      text-decoration: line-through; /* just for demonstration */
    }
    <div class="post">
      <a name="123"></a>
      <h3 class="post-title">Post</h3>
      <div class="NewPermalinkUrl">Text</div>
      <div class="post-body">
        <p>Content</p>
        <p>Not removed</p>
        <p>Not removed</p>
      </div>
    </div>
    
    <div class="post">
      <a name="456"></a>
      <h3 class="post-title">Post</h3>
      <div class="NewPermalinkUrl">Text</div>
      <div class="post-body">
        <p>Content</p>
        <p>To be removed</p>
        <p>To be removed</p>
      </div>
    </div>
    
    <div class="post">
      <a name="789"></a>
      <h3 class="post-title">Post</h3>
      <div class="NewPermalinkUrl">Text</div>
      <div class="post-body">
        <p>Content</p>
        <p>To be removed</p>
        <p>To be removed</p>
      </div>
    </div>
    Login or Signup to reply.
  2. use .prevAll()

    Get all preceding siblings of each element in the set of matched
    elements, optionally filtered by a selector, in the reverse document
    order.

    more about jQuery Traversing

    $('.post-body').each(function() {
      const $this = $(this);
      if ($(this).prevAll('[name="123"]').length == 0) {
        $(this).find('p').not(":first").remove();
      }
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
    <div class="post">
      <a name="123"></a>
      <h3 class="post-title">Post</h3>
      <div class="NewPermalinkUrl">Text</div>
      <div class="post-body">
        <p>Content1</p>
        <p>Content1</p>  <!-- fix function so this isn't removed -->
        <p>Content1</p>  <!-- fix function so this isn't removed -->
      </div>
    </div>
    
    <div class="post">
      <a name="456"></a>
      <h3 class="post-title">Post</h3>
      <div class="NewPermalinkUrl">Text</div>
      <div class="post-body">
        <p>Content2</p>
        <p>Content2</p>      <!-- this is currently removed -->
        <p>Content2</p>      <!-- this is currently removed -->
      </div>
    </div>
    
    <div class="post">
      <a name="789"></a>
      <h3 class="post-title">Post</h3>
      <div class="NewPermalinkUrl">Text</div>
      <div class="post-body">
        <p>Content3</p>
        <p>Content3</p>     <!-- this is currently removed -->
        <p>Content3</p>     <!-- this is currently removed -->
      </div>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search