I'm pretty new to JavaScript and all I want to do is when you click on a button it will make an image appear in a random spot.

What I've tried:

 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("imglink"); 
}

But that doesn't even make a new element.

Can someone tell me the correct code?

2 Answers

1
bambam On Best Solutions

You have a little error in appendChild, you should append the created element instead. Other than that, simply set top and left to something random and you're ready to go

function show_image(src, width, height, alt) {
  var img = document.createElement("img");
  img.src = src;
  img.width = width;
  img.height = height;
  img.alt = alt;
  
  // set the position
  img.style.position = 'absolute';
  img.style.top = document.body.clientHeight * Math.random() + 'px';
  img.style.left = document.body.clientWidth * Math.random() + 'px';

  document.body.appendChild(img);
}
document.getElementById('foo').addEventListener('click', () =>
  show_image("http://placekitten.com/200/300", 200, 300, 'foo')
);
html,
body {
  height: 100vh;
  width: 100vh;
}
<button id="foo">
  Get a cat
</button>

1
David On

There is a problem in the code you already have. The appendChild method takes an HTMLElement, not a String.

However, to execute a function on click, you have to add an eventlistener to the element you want to be clickable. The method to create/add eventlisteners is called addEventListener. It takes the name of the event as a string ('click' in this case), a function to execute and (optionally) a boolean value.

<HTMLElement>.addEventListener('click', <Function>);

To add a click eventlistener to the <body> element for example, you'd write:

document.body.addEventListener('click', function () { /* do something */ });

Now for the creation of the <img>:

Like you already do, the createElement function is typically used to create HTMLElement instances. It takes the tagname of the element you want to create and returns a new HTMLElement. To add properties to that element, you can usually do it by assigning values to the properties. Bear in mind that you have to assing null to remove a property.

This creates a new <img> element and assigns properties to it.

var myImg = document.createElement('img');
myImg.alt = 'A picture of Bill Murray';
myImg.src = 'https://www.fillmurray.com/400/300';
myImg.width = 400;
myImg.height = 300;

To add that image to the DOM, you use appendChild. For placing it into the <body> element:

document.body.appendChild(myImg);

This adds the <img> to the end of the children of <body>.

Although you now know how to place the new element into the DOM, it won't be placed at a random position. For this, you need a combination of Math.random and innerWidth/innerHeight. Alternatively, use getBoundingClientRect.

function getRandomCoordsIn (element) {
  var rect = element.getBoundingClientRect();
  // rect has 4 numeric properties: top, left, width, height
  // we return a pair of values which always is inside the element passed
  return [
    rect.top + Math.random() * rect.height, // top
    rect.left + Math.random() * rect.width  // left
  ];
}

Let's see what we can do with this:

document.body.addEventListener('click', handleClick);

function handleClick () {
  var coords = getRandomCoordsIn(document.body);

  var myImg = document.createElement('img');
  myImg.alt = 'A picture of Bill Murray';
  myImg.src = 'https://www.fillmurray.com/400/300';
  myImg.width = 400;
  myImg.height = 300;

  // This assigns inline CSS styles
  myImg.style.top = coords[0] + 'px';
  myImg.style.left = coords[1] + 'px';

  document.body.appendChild(myImg);
}

function getRandomCoordsIn (element) {
  var rect = element.getBoundingClientRect();
  // rect has some numeric properties, we need: top, left, width, height
  // we return a pair of coordinates which is located inside
  // the element passed
  return [
    rect.top + Math.random() * rect.height, // top
    rect.left + Math.random() * rect.width  // left
  ];
}

You'll also need some styles:

html { height: 100vh; overflow: auto; }
body { min-height: 100%; }
img { position: absolute; display: block; }