MAZ
MAZ

Reputation: 214

Check if a P tag has an IMG tag with specific id

I have a html page with this code :

<p>
    <img src="path.jpg" id="img_2">
</p>

How I can select with JS any <p> that contain an <img id="img_2"> :

I tried this but not working :

 if $('p:has(img#img_2)'){
    action here
 }

Upvotes: 0

Views: 1117

Answers (4)

Mike
Mike

Reputation: 1327

Debugging

Your code:

if $('p:has(img#img_2)'){
  action here
}

Has the following issues:

  • no parentheses around the condition expression
  • jQuery object always returns truthy

Corrected:

// .length is used to for detection and results in truthy/falsy expression 
if ( $('p:has(img#img_2)').length ){ 
  action here
}

Detecting Parent/Child

Element detection can be easily accomplished natively, without using jQuery.

1. Walking-Up

This approach finds an element and walks up the DOM tree. closest and parentNode are used to clearly describe intent; since it's desired that the closest p is the parent and not some ancestor. In production, you may want to add checks to insure img is found before looking for the parent -- a quick way is to add img && at the front of the condition.

const img = document.querySelector('#img_2')

if (img.closest('p') == img.parentNode)
  console.log('found')
  
if (img.closest('p') != img.parentNode)
  console.log('not found')
<p>
  <img src="path.jpg" id="img_2">
</p>

2. Walking-Down

This is accomplished by finding the paragraph and searching for it's children.

const p = document.querySelector('p')

if (p.querySelector('#img_1'))
  console.log('found 1')
  
if (p.querySelector('#img_2'))
  console.log('found 2')       // not found
<p>
  <img src="path.jpg" id="img_1">
  <div><img src="path.jpg" id="img_2"></div>
</p>

3. Trusting Child-Selector

This is using the child > selector to retrieve elements and then evaluating if the elements were found. Provided are both sides of the conditional to illustrate how to detect a non-match. Generally, the else would suffice.

const img1 = document.querySelector('p > #img_1')
const img2 = document.querySelector('p > #img_2')


if (img1)
  console.log('found img_1')                    // not reached
if (!img1)
  console.log('no paragraph with #img_1 child')
  
  
if (img2)
  console.log('found "p>#img_2"; paragraph: ', img2.parentNode)
if (!img2)
  console.log('no paragraph with #img_2 child') // not reached
<!-- outside -->
<img src="path.jpg" id="img_1">

<!-- inside -->
<p>
  <img src="path.jpg" id="img_2">
</p>

Upvotes: 2

ROOT
ROOT

Reputation: 11622

using > Child Combinator Something like this:

console.log($('p > img#img_2').length);
<script
  src="https://code.jquery.com/jquery-3.4.1.min.js"
  integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
  crossorigin="anonymous"></script>
<p>
    <img src="path.jpg" id="img_2">
</p>

Upvotes: 0

Zuckerberg
Zuckerberg

Reputation: 2161

You can use length property like:

if ($('p').find('img#img_2').length) {
  console.log('Image found!')
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>
  <img src="path.jpg" id="img_2">
</p>

Or,

if ($('p > img#img_2').length) {
  console.log('Image found!')
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>
  <img src="path.jpg" id="img_2">
</p>

Or your code should also be working with () like:

if ($('p:has(img#img_2)')) {
  console.log('Image found!')
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>
  <img src="path.jpg" id="img_2">
</p>

Upvotes: 2

Mamun
Mamun

Reputation: 68943

You should wrap the jquery object inside (). Also you have to use the length property of the object:

if ($('p:has(img#img_2)').length){
    console.log('Exists');
 }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>
  <img src="path.jpg" id="img_2">
</p>

Upvotes: 2

Related Questions