'Block disappears if there is no image in it
All health and happiness! A written script that should iterate through all the pictures, if the pictures did not load, then the script should hide the parent block under the .Parent_block class, that is, I have 3 blocks, there is a picture in the central block, but not in the other two, which means they should have property display:none
But I did something wrong. Where did I make a mistake?
let parent_block = document.querySelectorAll('.Parent_block');
let image_b = document.querySelectorAll('.Child_Img');
image_b.forEach(function(){
if(image_b.onerror){
for(let parent_block of hide){
hide.style.display = 'none';
}
}
})
.Parent_block{
width:30%;
margin:0;
padding:0;
margin-left:10px;
margin-top:10px;
border:1px solid black;
display:inline-block;
height:250px;
}
img{
height:inherit;
width:100%;
<figure class="Parent_block"> <!-- ***** this block should disappear ***** =( -->
<img class="Child_Img" src="">
<figcaption class ="Img_text">1</figcaption>
</figure>
<figure class="Parent_block">
<img class="Child_Img" src="https://i.ibb.co/kyXhZmB/photo-2021-11-18-14-40-18.jpg">
<figcaption class ="Img_text">2</figcaption>
</figure>
<figure class="Parent_block"> <!-- ***** and this one too ***** =( -->
<img class="Child_Img" src="">
<figcaption class ="Img_text">3</figcaption>
</figure>
Solution 1:[1]
There are some issues with the script.
- You are running
image_b.forEachand inside that you are trying to accessimage_b.onerror. This will not work sinceimage_bis an array. onerroris an event and not a property. So it cannot be accessed like this.- The syntax
for(let parent_block of hide)is wrong.
Fixed Code
Logic
- Select all elements with class name
Child_Img. - Loop through the elements and register
onerrorevent on each element in the list that we selected with class nameChild_Img. - On the error event, find the closest element with class name
Parent_blockand hide it.
Working Fiddle
let image_b = document.querySelectorAll('.Child_Img');
image_b.forEach(function (img) {
img.onerror = function(image) {
img.closest(".Parent_block").style.display = 'none';
}
})
.Parent_block {
width: 30%;
margin: 0;
padding: 0;
margin-left: 10px;
margin-top: 10px;
border: 1px solid black;
display: inline-block;
height: 250px;
}
img {
height: inherit;
width: 100%;
}
<figure class="Parent_block">
<!-- ***** this block should disappear ***** =( -->
<img class="Child_Img" src="">
<figcaption class="Img_text">1</figcaption>
</figure>
<figure class="Parent_block">
<img class="Child_Img" src="https://i.ibb.co/kyXhZmB/photo-2021-11-18-14-40-18.jpg">
<figcaption class="Img_text">2</figcaption>
</figure>
<figure class="Parent_block">
<!-- ***** and this one too ***** =( -->
<img class="Child_Img" src="">
<figcaption class="Img_text">3</figcaption>
</figure>
Solution 2:[2]
let parent_block = document.querySelectorAll('.Parent_block');
let image_b = document.querySelectorAll('.Child_Img');
image_b.forEach(function(image){
// check if any error (if image doesn't load in our case)
image.addEventListener("error",()=>{
// find closest class name and hide it
image.closest(".Parent_block").style.display = "none";
})
})
.Parent_block{
width:30%;
margin:0;
padding:0;
margin-left:10px;
margin-top:10px;
border:1px solid black;
display:inline-block;
height:250px;
}
img{
height:inherit;
width:100%;
<figure class="Parent_block"> <!-- ***** this block should disappear ***** =( -->
<img class="Child_Img" src="">
<figcaption class ="Img_text">1</figcaption>
</figure>
<figure class="Parent_block">
<img class="Child_Img" src="https://i.ibb.co/kyXhZmB/photo-2021-11-18-14-40-18.jpg">
<figcaption class ="Img_text">2</figcaption>
</figure>
<figure class="Parent_block"> <!-- ***** and this one too ***** =( -->
<img class="Child_Img" src="">
<figcaption class ="Img_text">3</figcaption>
</figure>
Solution 3:[3]
A very minimal solution could be done in the HTML. Remove all of your JS, and just change the <img> tags like so:
<img class="Child_Img" src="" onerror="this.parentElement.style.display = 'none';">
Solution 4:[4]
There are a number of problems with your script.
Some examples:
onerrorshould not be checked withif, but with event listener.forEachneeds an argument, you haven't provided any.- You should add
.onerrorto the argument offoreach, and not directly toimage_b - There is no variable declared as
hidein your script. I am guessing you intendedfor (let hide of parent_block) - Assuming you fixed everything up to #4, the loop runs
hide.style.display = 'none'for everything of parent_block, and not just the ones that includes the images with errors.
The following should work:
let parent_block = document.querySelectorAll('.Parent_block');
let image_b = document.querySelectorAll('.Child_Img');
image_b.forEach(function (cur_image) {
cur_image.onerror = function () {
for(let block of parent_block){
if(block.contains(cur_image) ){
block.style.display = 'none';
}
}
}
})
But the loop over the parent_block is not necessary, you can just find the relevant ancestor of the cur_image:
// let parent_block = document.querySelectorAll('.Parent_block');
let image_b = document.querySelectorAll('.Child_Img');
image_b.forEach(function (cur_image) {
cur_image.onerror = function () {
let hide = cur_image.closest('.Parent_block')
hide.style.display = 'none';
}
})
Note that it's not even to required to run document.querySelectorAll('.Parent_block') anymore.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Nitheesh |
| Solution 2 | Codenewbie |
| Solution 3 | Nicolas Goosen |
| Solution 4 |
