hey I wrote a JavaScript code and I managed to make the image change every few seconds but the text is changing alongside with the image but not the correct text is shown here is the code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href=
"https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">
<style>
img{
height: 500px;
width: 450px;
}
h1{
color: darkgreen;
margin-top: 20px;
font-family: Comic Sans MS, cursive, sans-serif;
}
.button{
margin-left: 45%;
}
</style>
<script>
function changeImage() {
var img = document.getElementById("img");
img.src = images[x];
x ;
if(x >= images.length) {
x = 0;
}
setTimeout("changeImage()", 6000);
}
function changeText() {
var txt= document.getElementById("message");
txt.textContent = text[y];
y ;
if(y>= text.length){
y = 0;
}
setTimeout("changeText()", 6000);
}
var text = [], y=0;
text[0] = "MSG1";
text[1] = "MSG2";
text[1] = "MSG3";
setTimeout("changeText()", 6000);
var images = [], x = 0;
images[0] = "image1.jpg";
images[1] = "image2.jpg";
images[2] = "image3.jpg";
setTimeout("changeImage()", 6000);
</script>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-3"></div>
<div class="col-md-6">
<h1 id="message">
Hello
</h1>
<img id="img"
src="image1.jpg" >
</div>
<div class="col-md-3"></div>
</div>
</div>
</body>
</html>
is there any efficient way to do it my goal is to make 3-5 images on an html webpage that change between each other every few seconds and each image has a different text above it
CodePudding user response:
Combine your two functions into one, so both things happen at the same time:
<script>
function changeImageAndText() {
var img = document.getElementById("img");
img.src = images[x];
var txt = document.getElementById("message");
txt.textContent = text[x];
x ;
if (x >= images.length) {
x = 0;
}
setTimeout("changeImageAndText()", 6000);
}
var text = [],
images = [],
x = 0;
text[0] = "MSG1";
text[1] = "MSG2";
text[2] = "MSG3";
images[0] = "image1.jpg";
images[1] = "image2.jpg";
images[2] = "image3.jpg";
setTimeout("changeImageAndText()", 6000);
</script>
CodePudding user response:
Instead of maintaining two arrays have one array of objects each of which contains image and text information. You can then create markup containing both sets of information at once rather than relying on two functions.
This working example uses images from dummyimage.com.
const data = [
{ image: 'https://dummyimage.com/100x100/666/ff0', text: 'Image 1' },
{ image: 'https://dummyimage.com/100x100/222/ff0', text: 'Image 2' },
{ image: 'https://dummyimage.com/100x100/fff/000', text: 'Image 3' },
{ image: 'https://dummyimage.com/100x100/a45/000', text: 'Image 4' },
];
// Cache the element
const div = document.querySelector('div');
// `carousel` is the main function into which we
// pass the data
function carousel(data) {
// `loop` is what `setTimeout` calls every second
// We initialise `count` to 0
function loop(count = 0) {
// Create the HTML using a template string
const html = `
<figure>
<img src="${data[count].image}" />
<figcaption>${data[count].text}</figcaption>
</figure>`;
// Add the markup to the div
div.innerHTML = html;
// Reset the count if we've reached the
// end of the array, otherwise increment it
if (count === data.length - 1) {
count = 0;
} else {
count;
}
// Call `loop` every second with the
// updated `count` variable
setTimeout(loop, 1000, count);
}
loop();
}
carousel(data);
<div></div>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
Additional information
CodePudding user response:
Your code is basically fine as far as timing goes - with intervals as long as 6 seconds you aren't going to notice if one timeout happens a microsecond after the other.
Your problem is a straightforward bug. There is a repetition of text[1] so the MSG2 never gets shown.
This is your snippet with just that change made and it works perfectly.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">
<style>
img {
height: 500px;
width: 450px;
}
h1 {
color: darkgreen;
margin-top: 20px;
font-family: Comic Sans MS, cursive, sans-serif;
}
.button {
margin-left: 45%;
}
</style>
<script>
function changeImage() {
var img = document.getElementById("img");
img.src = images[x];
x ;
if (x >= images.length) {
x = 0;
}
setTimeout("changeImage()", 6000);
}
function changeText() {
var txt = document.getElementById("message");
txt.textContent = text[y];
y ;
if (y >= text.length) {
y = 0;
}
setTimeout("changeText()", 6000);
}
var text = [],
y = 0;
text[0] = "MSG1";
text[1] = "MSG2";
text[2] = "MSG3";
setTimeout("changeText()", 6000);
var images = [],
x = 0;
images[0] = "image1.jpg";
images[1] = "image2.jpg";
images[2] = "image3.jpg";
setTimeout("changeImage()", 6000);
</script>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-3"></div>
<div class="col-md-6">
<h1 id="message">
Hello
</h1>
<img id="img" src="image1.jpg">
</div>
<div class="col-md-3"></div>
</div>
</div>
</body>
</html>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
However, you mention efficiency, and again at such long time intervals it probably isn't going to make a great deal of difference as the JS is only called every 6 seconds but if you want to make more efficient code then consider ditching JS and using CSS animations instead - the browser will have a chance of using the GPU then.
CodePudding user response:
The way I would do it is this:
const text = ["MSG1", "MSG2", "MSG3"];
const image = ["image1.jpg", "image2.jpg", "image3.jpg"];
const imageObj = document.GetElementById("img");
const textObj = document.GetElementById("message");
let counter = 0;
function ChangeImage() {
if (counter == text.length) {
counter = 0;
}
textObj.innerText = text[counter];
imageObj.src = image[counter];
counter ;
}
setInterval(ChangeImage, 3000); // 3000 = 3 Seconds, 5000 = 5 seconds.
The main thing to remember is to reduce the amount of times you repeat yourself, when looping through an array (when the pointer will be the same always) use the same variable (in this case counter)