1

So I want to see if there's an <img>inside my <div id="wrapper">

I know how to do this with jQuery. Now I want to translate it to plain JavaScript but I'm not sure how to use DOM selector to replicate the jQuery.

My jQuery solution

if ($('#wrapper img').length !== 0) {
  alert("img");
} else {
  alert("no img");
}
if ($('#wrapper2 img').length !== 0) {
  alert("img");
} else {
  alert("no img");
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id="wrapper">

</div>
<div id="wrapper2">
  <img src="" alt="">
</div>
kukkuz
  • 41,512
  • 6
  • 59
  • 95
Samuel Charpentier
  • 599
  • 1
  • 7
  • 28
  • 3
    `document.querySelectorAll('#wrapper img').length > 0` – haim770 Jan 03 '17 at 18:07
  • Possible duplicate of [Get element inside element by class and ID - JavaScript](http://stackoverflow.com/questions/7815374/get-element-inside-element-by-class-and-id-javascript) or http://stackoverflow.com/questions/7171483/simple-way-to-get-element-by-id-within-a-div-tag – Heretic Monkey Jan 03 '17 at 18:12
  • @haim770 It's better to use `querySelector()`, rather than `querySelectorAll()` as `querySelectorAll()` could wind up with a much higher performance cost depending on the depth of the DOM. – Scott Marcus Jan 03 '17 at 18:39
  • @MikeMcCaughan This question and answer in the other post that you marked is NOT the same as this answer. No where on that page is `querySelector` (which is the best answer) even mentioned. That other page repeatedly suggests `getElementsByClassName()`, which should not be used for this question. – Scott Marcus Jan 04 '17 at 01:09
  • @ScottMarcus You're free to vote to reopen, but it certainly is a duplicate of another question. Note the second question in the Linked section. – Heretic Monkey Jan 04 '17 at 14:42
  • @MikeMcCaughan Let me re-phrase, yes, the question is the same as the one you linked to, but the answer posted there is really not the best answer. Perhaps it was when the post was made, but there is no mention of `querySelector()` on that page and that is the best and correct answer. Just closing questions because another one with bad, wrong or out of date answers exist is not what that SO feature is for. – Scott Marcus Jan 04 '17 at 15:13
  • Then add your answer to the duplicate question to improve the answers to that question. Now we have at least three questions asking the same thing. That is precisely what the SO feature is meant to counteract. When you find a question with outdated answers, you should add an updated answer to the question. See http://meta.stackoverflow.com/q/263122/215552 and http://meta.stackoverflow.com/q/255198/215552. – Heretic Monkey Jan 04 '17 at 15:18

4 Answers4

4

Here's a simple solution

if( document.getElementById('wrapper').getElementsByTagName('img').length > 0) {
    // Image present
 }
haim770
  • 48,394
  • 7
  • 105
  • 133
Bidhan
  • 10,607
  • 3
  • 39
  • 50
  • `querySelector()` should be used instead of `getElementsByTagName()` because (depending on the depth of the DOM), `querySelector()` will perform better as it will stop querying after the first match is found. – Scott Marcus Jan 04 '17 at 01:12
3

You can use:

document.getElementById('wrapper').getElementsByTagName('img');

alongside with an if statement where you check if there's an image in the div with wrapper id:

if (document.getElementById('wrapper').getElementsByTagName('img').length !== 0) {
   console.log('img found');
}else{
  console.log('no img');
}
<div id="wrapper">

</div>
<div id="wrapper2">
<img src="" alt="">
</div>

You can read more about: document.getElementById() and getElementsByTagName()

Ionut Necula
  • 11,107
  • 4
  • 45
  • 69
  • `querySelector()` should be used instead of `getElementsByTagName()` because (depending on the depth of the DOM), `querySelector()` will perform better as it will stop querying after the first match is found. – Scott Marcus Jan 04 '17 at 01:11
2

You can use querySelectorAll function - see demo below:

if (document.querySelectorAll('#wrapper img').length !== 0) {
  console.log("img");
} else {
  console.log("no img");
}
if (document.querySelectorAll('#wrapper2 img').length !== 0) {
  console.log("img");
} else {
  console.log("no img");
}
<div id="wrapper">

</div>
<div id="wrapper2">
  <img src="" alt="">
</div>
kukkuz
  • 41,512
  • 6
  • 59
  • 95
  • It's better to use `querySelector()`, rather than `querySelectorAll()` as `querySelectorAll()` could wind up with a much higher performance cost depending on the depth of the DOM. – Scott Marcus Jan 04 '17 at 01:12
2

querySelector() is the DOM API method that you should use.

You should use this instead of querySelectorAll() (as some have mentioned) as this will perform better because it only looks for a single match and stops after finding one. Depending on the depth of your DOM, using querySelector() instead of querySelectorAll() or getElementsByTagName() can positively impact performance of the code.

This snippet shows a simple function that you can call anytime you need to do this check. If a nested <img> element is found, then you have a "truthy" result that you can test for with an if and if no nested <img> is found, then you have a "falsy" result that the same if condition can test for.

// Get DOM references to the wrappers you wish to test:
var wrap1 = document.getElementById("wrapper");
var wrap2 = document.getElementById("wrapper2");

// General function to test any DOM element for a descendant image.
function testImage(wrap){
  // querySelector will return the first element that matches the query
  // If no element is matched, no element is returned (null)
  
  // Using the JavaScript "ternary" operator here to test the "truthy" or
  // "falsy" result of querySelector on the supplied DOM object. If there is
  // a nested image message becomes an empty string, but if there is no nested
  // image, message becomes " not". Of course, you can change this to any
  // values/operations you want to perform based on the result of the test.
  var message = wrap.querySelector("img") ? "" : " not";
  
  // Write a message and use the string determined in the previous line:
  console.log("There is" + message + " an image inside " + wrap.id)
}


// Run the function as often as you liike:
testImage(wrap1);
testImage(wrap2);
<div id="wrapper">

</div>
<div id="wrapper2">
 <img src="" alt="">
</div>
Scott Marcus
  • 64,069
  • 6
  • 49
  • 71
  • So .querySelector returns true of false instead? – Samuel Charpentier Jan 03 '17 at 18:25
  • 1
    `querySelector` returns a reference to the first DOM node that matches the query. If there is a match, you get an object reference, which converts to `true` for the purposes of using it as the basis of an `if` condition (because an object is a "truthy" value in JavaScript). If no node is found, it returns `null`, which converts to `false` for purposes of an `if` condition (because `null` is "falsy" value in JavaScript). – Scott Marcus Jan 03 '17 at 18:28