I'm new to javascript and trying to write a script to change the url of an image on my website back and forth using two buttons.
I somehow managed to do the forward stepping one, using the code below, but can't figure out how to do the same backwards.
var trafficlights = [
'images/csp-1.png',
'images/csp-2.png',
'images/csp-3.png',
'images/csp-4.png',
'images/csp-5.png',
'images/csp-6.png',
'images/csp-7.png',
'images/csp-8.png',
];
var num = 1
function lightsequence() {
document.getElementById('my-image').src = trafficlights[num % trafficlights.length];
}
<div >
<button id="previous" onclick="lightsequence2()"> <img src="images/left.png"> </button>
<button id="next" onclick="lightsequence()"> <img src="images/right.png"> </button>
</div>
<img id="my-image" src="images/csp-1.png">
Any leads greatly appreciated!
CodePudding user response:
Add the length to the new number before the modulo to loop back, so:
num = (num-- trafficlights.length) % trafficlights.length
This also doesn't break incrementing forward, so you can use one function:
var trafficlights = [
'https://upload.wikimedia.org/wikipedia/commons/thumb/6/6e/Zéro.svg/120px-Zéro.svg.png',
'https://upload.wikimedia.org/wikipedia/commons/thumb/0/08/Un1.svg/120px-Un1.svg.png',
'https://upload.wikimedia.org/wikipedia/commons/thumb/3/3b/Deux.svg/120px-Deux.svg.png',
'https://upload.wikimedia.org/wikipedia/commons/thumb/6/6d/Trois.svg/120px-Trois.svg.png'
];
var num = 0
function lightsequence(increment) {
num = (num increment trafficlights.length) %trafficlights.length
document.getElementById('my-image').src = trafficlights[num];
}
<div >
<button id="previous" onclick="lightsequence(-1)"> Back </button>
<button id="next" onclick="lightsequence(1)"> Next
</div>
<img id="my-image" src="https://upload.wikimedia.org/wikipedia/commons/thumb/6/6e/Zéro.svg/120px-Zéro.svg.png">
CodePudding user response:
You can eliminate the inline JS by attaching a listener to the buttons' parent element which can catch events from its child elements as they "bubble up" the DOM (known as event delegation). Check that the child element is a button, and then run the rest of the function.
Check which button fired the click event by its
id
. If it's "previous" reducenum
; "next", increasenum
.
const trafficlights=["https://dummyimage.com/50x50/000/fff&text=Light","https://dummyimage.com/50x50/aaa/000&text=Light","https://dummyimage.com/50x50/456/fff&text=Light","https://dummyimage.com/50x50/ff0/000&text=Light","https://dummyimage.com/50x50/9a4/000&text=Light","https://dummyimage.com/50x50/1a5/fff&text=Light"];
// Cache the elements
const image = document.querySelector('.tap-image');
const buttons = document.querySelector('.tap-control-buttons');
// Add a listener to the containing element
buttons.addEventListener('click', handleClick);
let num = 0;
function handleClick(e) {
// If the child element that fired the event
// is a button...
if (e.target.matches('button')) {
// ...destructure its id
const { id } = e.target;
// ...decrease/increase the value of `num` within the
// bounds of the array
if (id === 'previous' && num > 0) --num;
if (id === 'next' && num < trafficlights.length - 1) num;
// Set the new image
image.src = trafficlights[num];
}
}
.tap-image { margin-top: 1em; }
.tap-control-buttons button { font-size: 1.2em; border-radius: 5px; }
.tap-control-buttons button:hover { background-color: lightblue; cursor: pointer; }
<div >
<button id="previous">