When someone clicks on one of these images I would like that image to appear as the background image of div "slides", and am not sure what is going wrong. Maybe I am not using "this" properly.
function showslide() {
y = document.getElementById("slides");
y.style.display = "block";
z = this.src;
y.backgroundImage = 'url(' + z + ')';
}
<div id="slides">Div</div>
<div id="slidermenu">
<img class="slidermenuimage" src="" onclick="showslide()"/><br>
<img class="slidermenuimage" src="" onclick="showslide()"/><br>
<img class="slidermenuimage" src="" onclick="showslide()"/><br>
</div>
When someone clicks on one of these images I would like that image to appear as the background image of div "slides", and am not sure what is going wrong. Maybe I am not using "this" properly.
function showslide() {
y = document.getElementById("slides");
y.style.display = "block";
z = this.src;
y.backgroundImage = 'url(' + z + ')';
}
<div id="slides">Div</div>
<div id="slidermenu">
<img class="slidermenuimage" src="https://placehold.co/600x400/red/white" onclick="showslide()"/><br>
<img class="slidermenuimage" src="https://placehold.co/600x400/orange/white" onclick="showslide()"/><br>
<img class="slidermenuimage" src="https://placehold.co/600x400/yellow/white" onclick="showslide()"/><br>
</div>
Share
Improve this question
edited Jan 19 at 6:44
mplungjan
178k28 gold badges180 silver badges240 bronze badges
asked Jan 19 at 3:27
googoo
171 silver badge2 bronze badges
4 Answers
Reset to default 0Instead of using this, pass event into your functions. Then use event.target
You also need to use y.style.backgroundImage You left out the .style
By default the slides div has 0px height, so you need to set a height to see the background image.
See my EDIT comments in the code snippet for specific edits.
// EDIT add event as a parameter
// function showslide() {
function showslide(event) {
y = document.getElementById("slides");
y.style.display = "block";
// EDIT Use event.target instead of this
// z = this.src;
z = event.target.src;
// EDIT You need .style
// y.backgroundImage = 'url('+z+')';
y.style.backgroundImage = 'url('+z+')';
}
/* EDIT slides needs a height so you can see the background image */
#slides {
height: 100px;
}
/* EDIT For the demo */
.slidermenuimage {
margin: 1rem;
width: 64px;
}
<div id="slides"></div>
<div id="slidermenu">
<img class="slidermenuimage" src="https://placebear.com/400/400.jpg" onclick="showslide(event)"/><br>
<img class="slidermenuimage" src="https://placebear.com/401/400.jpg" onclick="showslide(event)"/><br>
<img class="slidermenuimage" src="https://placebear.com/402/400.jpg" onclick="showslide(event)"/><br>
</div>
Yes you are using this
wrong, because you use inline event handlers which is not recommended. See the other answer for the inline handling
Also the assignment of backgroundImage is missing style.
Instead use addEventListener on the container so you can delegate
window.addEventListener('load', () => { // when the elements are available
const slides = document.getElementById("slides");
document.getElementById('slidermenu').addEventListener('click', (event) => {
const tgt = event.target;
if (!tgt.matches('.slidermenuimage')) return; // not an image
slides.style.backgroundImage = `url(${tgt.src})`;
});
});
#slides {
width: 600px;
height: 400px;
border: 1px solid black;
}
.slidermenuimage {
border: 1px solid white;
}
<div id="slides">Div</div>
<div id="slidermenu">
<img class="slidermenuimage" src="https://placehold.co/600x400/red/white" /><br>
<img class="slidermenuimage" src="https://placehold.co/600x400/orange/white" /><br>
<img class="slidermenuimage" src="https://placehold.co/600x400/yellow/white" /><br>
</div>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Image Click Example</title>
<style>
#slides {
width: 600px;
height: 400px;
background-color: lightgray;
background-size: cover;
background-position: center;
}
#slidermenu {
margin-top: 20px;
}
.slidermenuimage {
cursor: pointer;
margin-bottom: 10px;
width: 100px;
}
</style>
</head>
<body>
<div id="slides"></div>
<div id="slidermenu">
<img class="slidermenuimage" src="https://placehold.co/600x400/red/white" alt="Red Image" /><br>
<img class="slidermenuimage" src="https://placehold.co/600x400/orange/white" alt="Orange Image" /><br>
<img class="slidermenuimage" src="https://placehold.co/600x400/yellow/white" alt="Yellow Image" /><br>
</div>
<script>
// Wait for the DOM to load
document.addEventListener("DOMContentLoaded", function () {
// Select all images with the class "slidermenuimage"
const images = document.querySelectorAll(".slidermenuimage");
// Add a click event listener to each image
images.forEach(function (image) {
image.addEventListener("click", function () {
// Get the source of the clicked image
const imgSrc = this.getAttribute("src");
// Set the background of the #slides div
const slides = document.getElementById("slides");
slides.style.backgroundImage = `url(${imgSrc})`;
});
});
});
</script>
</body>
</html>
Event Delegation
Although it's big in React, inline event handlers (or on-event handlers) are still discouraged. Use
addEventListener()
method.If you have multiple elements needing an event handler❇, add the event handler (via
addEventListener()
to an ancestor element they all have in common. That could bewindow
,document
,body
, etc. but it's better if you choose the closest one to the elements you intend to interact with. In your particular layout that would be#slidermenu
(in Demo it's renamed#image-menu
). See Example 1 below.Example 1
<div id="ancestor"> <!-- Add event handler here... --> <img ...> <!-- if you want to control all of the children --> <img ...> <img ...> </div>
❇ event handler is a function that's used to handle an event via
.eventListener()
, on-property✳, or on-event.
✳ on-property looks like this:
element.onclick = eventHandler;
When you write your event handler, you determine which elements will react to the event and exclude all other elements simply by not even mentioning them. To help you sort out the specific element the user interacted with (eg. "clicked"), use the event.target property. See Example 2 below.
Example 2
// Event object is passed by default const eventHandler = (event) => { // Find out which element user clicked const clk = event.target; // Specify which elements you want if (clk.matches("img")) { // Define what happens here } /** * You don't need to do anything else unless there * are other elements you wish to have react. */ }; // Reference ancestor element const parent = document.getElementById("ancestor"); // Register ancestor to "click" event parent.addEventListener("click", eventHandler);
The advantages of event delegation are:
- Unlimited amount of elements you can control.
- Control over any elements dynamically added later on.
- You only need one event handler/listener for each
event.type
.
The disadvantage would be that there's more planning?
Other Concerns
Remember to use
let
orconst
when defining variables. There were nolet
orconst
fory
andz
so they became global.style
property wasn't used when assigning a value forbackgroundImage
.You don't need to assign
display: block
to a<div>
, they already are by default.It's a fair assumption that
display: block
was used because the image never appeared. If there wasn't an error (see #2), the image would still not be visible. Becausebackground-image
is just a style and not content like an element or text. An element's height depends on it's content unless it's explicitly defined. In Demomin-height: 100px
was added to#slides
.Note:
cssText
property was used to add multiple styles. Using juststyle.CSSProperty = CSSValue
will be overwritten if used again. So usingcssText
to define multiple styles all at once is better. If at sometime later you wish to add additional styles you can use+=
operand if you don't want to overwrite what's already there.this
can be used if each<img>
was assigned a named function handler by eitheraddEventListener()
or an on-property. When usingthis
in an inline event handler it points to thewindow
object.
Demo
Details are commented in demo.
/**
* Handles "click" events. It assigns the
* src of the <img> the user clicked to
* div#slides.
* @param {object} event - Event object
*/
function showSlide(event) {
// This is the element the user clicked
const x = event.target;
// If the user clicked an <img>...
if (x.matches("img")) {
// reference div#slides...
const y = document.getElementById("slides");
// get the url of the clicked <img>
const z = event.target.src;
// assign the styles to div#slides
y.style.cssText = `
min-height: 100px;
background-image: url("${z}");`;
}
}
/**
* Register div#image-menu to listen for the
* "click" event when triggered on itself
* and it's children (eg. all <img>s).
*/
document.getElementById("image-menu")
.addEventListener("click", showSlide);
<div id="slides"></div>
<div id="image-menu">
<img id="x" src="https://placehold.co/100x100/red/white"/>
<img src="https://placehold.co/100x100/blue/yellow">
<img src="https://placehold.co/100x100/yellow/blue">
</div>