Home > Back-end >  Remove one image after another when onclick
Remove one image after another when onclick

Time:10-06

i have a div that contains 5 of the same image. i'm trying to make a button that can make one of the images disappear one after another when onclick. i've tried the style.visibility but it makes them all disappear together. This is my code

document.getElementById("btn1").onclick = function() {
  document.getElementById("output").style.visibility = "hidden";
}
<input id="btn1" type="button" value="Click me" onclick="onClick1()" style="height: 100px; width: 100px;">
<div style="margin-top: 40px;"></div>
<div id="output">
  <img src="/images/person1.jpg">
  <img src="/images/person1.jpg">
  <img src="/images/person1.jpg">
  <img src="/images/person1.jpg">
  <img src="/images/person1.jpg">
</div>

CodePudding user response:

You are targeting the image container and then hiding it so all the images disappear at once.

It's not really clear from your question whether you want to click the button once and have the images disappear, or to click the button repeatedly and have one image disappear on each click. This solution answers the first problem.

If you want to hide the images one-by-one you're going to need to use setInterval or setTimeout to manage that. In this example I've used setTimeout.

document.getElementById('btn1').onclick = function() {

  // Get all the images
  const images = Array.from(document.querySelectorAll('#output img'));

  // Loop over the images
  function loop(images) {

    // If there are images left remove the first one,
    // hide it, and then call the function again with the
    // reduced image array until all images are gone.
    if (images.length) {
      const image = images.shift();
      image.style.visibility = 'hidden';
      setTimeout(loop, 1000, images);
    }
  }
  loop(images);
}
<input id="btn1" type="button" value="Click me" onclick="onClick1()" style="height: 100px; width: 100px;">
<div style="margin-top: 40px;"></div>
<div id="output">
  <img src="https://dummyimage.com/30x30/000/fff">
  <img src="https://dummyimage.com/30x30/000/fff">
  <img src="https://dummyimage.com/30x30/000/fff">
  <img src="https://dummyimage.com/30x30/000/fff">
  <img src="https://dummyimage.com/30x30/000/fff">
  <img src="https://dummyimage.com/30x30/000/fff">
</div>

Additional documentation

If you want to make the images disappear on each click, cache the images, and return a function that the listener calls when you click the button.

const button = document.getElementById('btn1')
button.addEventListener('click', handleClick(), false);

// Cache the image elements, and then return a new
// function to your listener that removes an image on each click
function handleClick() {
  
  const images = Array.from(document.querySelectorAll('#output img'));

  return function() {
    if (images.length) {
      const image = images.shift();
      image.style.visibility = 'hidden';
    }
  }

}
<input id="btn1" type="button" value="Click me" style="height: 100px; width: 100px;">
<div style="margin-top: 40px;"></div>
<div id="output">
  <img src="https://dummyimage.com/30x30/000/fff">
  <img src="https://dummyimage.com/30x30/000/fff">
  <img src="https://dummyimage.com/30x30/000/fff">
  <img src="https://dummyimage.com/30x30/000/fff">
  <img src="https://dummyimage.com/30x30/000/fff">
  <img src="https://dummyimage.com/30x30/000/fff">
</div>

CodePudding user response:

  1. You should give id's to image tag instead of parent div.
  2. Created variable which which will work as a counter.
  3. On each click increase counter and hide the specific image tag.

Your code will look like:

let imageToDelete = 1;
document.getElementById("btn1").onclick = function() {
  document.getElementById("image_"   imageToDelete).style.visibility = "hidden";
  imageToDelete  ;
}
<input id="btn1" type="button" value="Click me" onclick="onClick1()" style="height: 100px; width: 100px;">
<div style="margin-top: 40px;"></div>
<div>
  <img id="image_1" src="/images/person1.jpg">
  <img id="image_2" src="/images/person1.jpg">
  <img id="image_3" src="/images/person1.jpg">
  <img id="image_4" src="/images/person1.jpg">
  <img id="image_5" src="/images/person1.jpg">
</div>

CodePudding user response:

With that script, all you are doing is hiding the parent of all the images, which results in all the images "seemingly disappearing" at once. You have to remove each separately to achieve your desired result.

const RemoveImage = Event => {
  const Target = Event.target;
  const ImgPos = Target.getAttribute("data-remove");
  const Selector = `#image-parent > img:${ImgPos}-of-type`;
  const ImgToRemove = document.querySelector(Selector);
  if(!ImgToRemove) return false;
  ImgToRemove.parentElement.removeChild(ImgToRemove);
  return true;
};




const Buttons = document.querySelectorAll("button[data-remove]");
Buttons.forEach(btn => btn.addEventListener("click", RemoveImage));
#image-parent > img:hover {
  filter: brightness(92%);
}
#first {outline: 2px solid #a00;}
#last {outline: 2px solid #0a0;}
<div id="image-parent">
  <img src="https://via.placeholder.com/70" id="first">
  <img src="https://via.placeholder.com/70">
  <img src="https://via.placeholder.com/70">
  <img src="https://via.placeholder.com/70" id="last">
</div>

<button data-remove="first">Remove first img</button>
<button data-remove="last">Remove last img</button>

If you don't want the images to be removed fully, but rather just hidden:

  • Rreplce the line ImgToRemove.parentElement.removeChild(ImgToRemove); with something like ImgToRemove.classList.add("hidden-by-css");
  • Then declare this CSS class with opacity: 0; pointer-events: none;.

CodePudding user response:

We know manipulating HTML DOM is not popular option. But this will work with your problem.

document.getElementById("btn1").onclick = function() {
  let imageNode = document.getElementById("output").getElementsByTagName('img')[0];
  imageNode.parentNode.removeChild(imageNode)
}

CodePudding user response:

I have found that using the queue() and dequeue() methods from jQuery library is a very good option for resolving this step by step scenarios. This is the stated description of this in the official page:

"Queues allow a sequence of actions to be called on an element asynchronously, without halting program execution. "

I will leave an brief example of how I have implemented it in the past:

$('#anchoredToElement')
     .queue("steps", function (next) {
        console.log("Step 1");
        //In case you want to hold the execution for a bit depending on the scenario you're running
        setTimeout(function () { console.log("Action within timeout") }, 500);
        next();
      })
      .queue("steps", function (next) {
        console.log("Step 2");
        setTimeout(function () {
            //Execution example
            UploadFile(fileUpload))
        }, 500);
        next();
            })
       .dequeue("steps");

Here an example of how I think the logic could be for your needs:

    var removeImage = function (index) {
        //Logic here to remove image within div according to passed index
    };

    var index = 0;
    $('#output')
        .queue("steps", function (next) {
            console.log("Remove Image 1");
            setTimeout(function () { removeImage(index); }, 250);
            index  ;
            next();
        })
        .queue("steps", function (next) {
            console.log("Remove Image 2");
            setTimeout(function () { removeImage(index); }, 250);
            index  ;
            next();
        })
        .queue("steps", function (next) {
            console.log("Remove Image 3");
            setTimeout(function () { removeImage(index); }, 250);
            index  ;
            next();
        })
        .queue("steps", function (next) {
            console.log("Remove Image 4");
            setTimeout(function () { removeImage(index); }, 250);
            index  ;
            next();
        })
        .queue("steps", function (next) {
            console.log("Remove Image 5");
            setTimeout(function () { removeImage(index); }, 250);
            index  ;
            next();
        })
    .dequeue("steps");

Of course you can improve the JS code as I was just focusing on the step by step process.

This is just a first glance of how $.queue can help you to achieve the step by step process. I recommend to go check the documentation to learn the details and so apply it to your logic as needed.

  • Related