Sander Dult
Sander Dult

Reputation: 35

button showing image only once?

Quick question,

I'm a complete JS noob, so I'm having a hard time finding the correct answer on the internet. So I figured I'd ask my question here.

I wrote these two functions.

<script language="javascript" type="text/javascript">

function test() {
show_image("nummer/test.jpg", 120,160, "Firstname Lastname");
show_image("nummer/test2.jpg", 120,160, "Firstname2 Lastname2");
}

function show_image(src, width, height, alt) {
    var img = document.createElement("img");
    img.src = src;
    img.width = width;
    img.height = height;
    img.alt = alt;
    document.body.appendChild(img);
}

//edited piece of code:

function removeImages(){
            var images = document.getElementsByTagName("img");
            for (index = images.length - 1; index >= 0; index--) {
                images[index].parentNode.removeChild(images[index]);
            }
        }

</script>

<button onclick="test();">test</button>

This displays the images perfectly fine, but when you keep clicking the button, it keeps generating images. So if you keep clicking the button, my page fills up with the same images.

I need a way to limit this. I'd like to make the image disappear again when the button is clicked the second time, or when another button is clicked.

Thanks!

EDIT:

Found the solution to my initial problem, the block code is now edited with an extra function to replace the images. I know my code is really not efficient, but it works.

Upvotes: 0

Views: 751

Answers (3)

Oceanity
Oceanity

Reputation: 194

Because you say "when another button is clicked", I assume you are trying to make it so there are multiple buttons, each one loading a different image.

If this is indeed the case, I'd go with the following approach:

// Array of image objects to keep things neat
var images = [
    { "src": "http://placehold.it/120x160", "width": "120", "height": "160", "alt": "Test Image 1" },
    { "src": "http://placehold.it/120x161", "width": "120", "height": "160", "alt": "Test Image 2" }
];
function show_image(image) {
    // Ensure provided index is in array
    if (image < images.length) {
        // Remove this image if already displayed
        if (document.getElementsByClassName("imageNo" + image)[0] !== undefined)
            document.getElementsByClassName("imageNo" + image)[0].outerHTML = "";
        else {
            // Remove other images if displayed
            if (document.getElementById("currentImage") !== null) 
                document.getElementById("currentImage").outerHTML = "";
            var img = document.createElement("img");
            var cur = images[image];
            img.id = "currentImage";
            img.className = "imageNo" + image;
            img.src = cur.src;
            img.width = cur.width;
            img.height = cur.height;
            img.alt = cur.alt;
            document.body.appendChild(img);
        }
    }
    else 
        console.log('No image exists for this index');
}
// Add functionality to buttons
document.getElementById("imageButton1").onclick = function() {show_image(0);}
document.getElementById("imageButton2").onclick = function() {show_image(1);}

Fiddle

If you have one button that you'd like to cycle through all the images, you could use the same approach but change show_image to

var currentImage = 0;
function show_image() {
    // Remove other images if displayed
    if (document.getElementById("currentImage") !== null) 
        document.getElementById("currentImage").outerHTML = "";
    var img = document.createElement("img");
    var cur = images[currentImage++ % images.length];
    img.id = "currentImage";
    img.src = cur.src;
    img.width = cur.width;
    img.height = cur.height;
    img.alt = cur.alt;
    document.body.appendChild(img);
}
function hide_image() {
    // Remove other images if displayed
    if (document.getElementById("currentImage") !== null) 
        document.getElementById("currentImage").outerHTML = "";
    currentImage = 0;
}
// Add functionality to buttons
document.getElementById("imageButton1").onclick = function() {show_image();}
document.getElementById("imageButton2").onclick = function() {hide_image();}

Fiddle

Hope one of these is what you are looking for.

EDIT:

For a multidimensional array you'll need to do the following:

// Array of image objects to keep things neat
var images = [
    //group 1
    [
        { "src": "http://placehold.it/120x160", "width": "120", "height": "160", "alt": "Test Image 1" },
        { "src": "http://placehold.it/120x161", "width": "120", "height": "160", "alt": "Test Image 2" }
    ],
    //group 2
    [
        { "src": "http://placehold.it/120x160", "width": "120", "height": "160", "alt": "Test Image 3" },
        { "src": "http://placehold.it/120x161", "width": "120", "height": "160", "alt": "Test Image 4" }
    ],
];

Obviously if you are going to have 800 images, this is going to be a bit more tedious. Are all the images going to be the same width/height? If they are, I'd take the hit on SEO to go for something like this:

var imageUrls = [
    "http://placehold.it/120x160",  
    "http://placehold.it/120x160", 
    //etc.
];
    // Change this as desired
var itemsPerGroup = 40;
// Returns how many times imageUrls length can be divided into 40 for group count
var images = new Array(Math.floor(imageUrls.length/itemsPerGroup) + 1);
// Initializes child arrays, ensuring last is only as long as it needs to be
for (var i=0; i<images.length; i++)
    images[i] = (i !== images.length - 1) ? new Array(itemsPerGroup) : new Array(images.length % itemsPerGroup);

// Fill arrays
for (var i=0; i<imageUrls.length; i++) {
    // current group
    var group = Math.floor(i/itemsPerGroup);
    // dividend is item number
    var item = i%itemsPerGroup;
    images[group][item] = {
        "src": imageUrls[i],
        "alt": "Group " + group + ", Image " + item,
        "width": "120",
        "height": "160"
    };
}

Using this you'll call images like so

// Array of currentImages
var currentImages = new Array(images.length);
// Initialize
for (var i=0; i<currentImages.length; i++)
    currentImages[i] = 0;

function show_image(group) {
    var imageID = "currentImage" + group;
    var imageContainer = "imageGroup" + group + "Container";
    // Remove other image in group if displayed
    if (document.getElementById(imageID) !== null) 
        document.getElementById(imageID).outerHTML = "";
    var img = document.createElement("img");
    var cur = images[group][currentImages[group]++%images[group].length];
    img.id = "currentImage" + group;
    img.src = cur.src;
    img.width = cur.width;
    img.height = cur.height;
    img.alt = cur.alt;
    document.getElementById(imageContainer).appendChild(img);
}
function hide_image(group) {
    // Remove image in group if displayed
    var imageID = "currentImage" + group;
    if (document.getElementById(imageID) !== null) 
        document.getElementById(imageID).outerHTML = "";
    // Reset currentImage
    currentImages[group] = 0;
}

And of course, a Fiddle showing it in action.

Upvotes: 0

rgthree
rgthree

Reputation: 7273

Edited after OP comment clarification. Think about what your show_image logic is doing. You are creating an image and attaching it each time your button is clicked

Now, what do you want to really do? Answer that, and you have your answer. Let's create a story: Each time I click my button I want to add my two images if they are not on screen, or remove them if they are.

There are a bunch of ways to do this. You could use CSS if you just want to visually hide them, you could destroy and create new images, you can attach/detach the same images, etc. But one thing remains the same: you need to keep track of whether or not the images you're creating have already been created. (This, also, has multiple ways; you could query the dom, you could store references to the items, you could use a boolean switch, etc.).

Here's a live example that uses your original code as a base but keeps track of the image reference we create only once and attaches or removes them from the dom with each button click:

// Define our images in the outer closure.
var img1, img2;

// Handle the button click
function toggleImages() {
  // If we haven't created our images, create and store them in
  // our variables.
  if (!img1) {
    img1 = create_image('http://lorempixel.com/120/160?a', 120, 160, "Firstname Lastname");
  }
  if (!img2) {
    img2 = create_image('http://lorempixel.com/120/160?b', 120, 160, "Firstname Lastname");
  }
  // Toggle our images
  toggle_image(img1);
  toggle_image(img2);
}

function create_image(src, width, height, alt) {
  var img = document.createElement('img');
  img.src = src;
  img.width = width;
  img.height = height;
  img.alt = alt;
  return img;
}

function toggle_image(img) {
  var parent = img.parentElement;
  // If our images are not attached to a parent, attach them.
  // Otherwise, remove them.
  if (!parent) {
    document.body.appendChild(img);
  } else {
    parent.removeChild(img);
  }
}
<button onclick="toggleImages()">Toggle some images!</button><br><br>

Upvotes: 1

noa-dev
noa-dev

Reputation: 3641

I had no time to test-run it, but I Hope that solves your problem:

Note I am selecting the img, that has been created and deleting it before appending another one

function test() {
var x = document.querySelector('img');
var body = document.querySelector('body');
if(x){ // if an img has been found do that
   body.removeChild(x);
}
show_image("nummer/test.jpg", 120,160, "Firstname Lastname");
show_image("nummer/test2.jpg", 120,160, "Firstname2 Lastname2");
}

function show_image(src, width, height, alt) {

    var img = document.createElement("img");
    img.src = src;
    img.width = width;
    img.height = height;
    img.alt = alt;
    document.body.appendChild(img);
}

Upvotes: 0

Related Questions