我有一个包含几个值的数组,每个值都是网站上的图片位置。
["img/image1.png", "img/image2.png", "img/image3.png", "img/image4.png"]
我需要遍历它们,并将它们作为src
属性每秒依次应用到图像,然后依次是image1,image2,image3等。
我真的很想使用for
循环,但是完全不知道从哪里开始...
答案 0 :(得分:2)
由于您想要的异步性质,我不认为for
循环在这里适用。
让我们考虑一下行为
# psuedocode
choose the next image
set image src
when the image has loaded
wait one second
loop from line #1
实施该逻辑
const images = ["https://via.placeholder.com/150", "https://via.placeholder.com/150x50", "https://via.placeholder.com/150x100", "https://via.placeholder.com/150x25"]
const image = document.querySelector('#image')
let currentImage = 0
function updateImage() {
// choose the next image
const newImageSrc = images[currentImage++ % images.length]
// set image src
image.src = newImageSrc
// when the image has loaded
image.onload = function () {
// wait one second (1000 milliseconds) and "loop"
setTimeout(updateImage, 1000)
}
}
// start with an image immediately without waiting
updateImage()
<img id="image">
此处的其他答案已使用setInterval
。我认为您应尽可能避免使用setInterval
,并使用带有自引用循环的setTimeout
。
考虑
function doSomethingIntesive() {
...
}
setInterval(doSomethingIntesive, 1000)
您想每秒呼叫doSomethingIntensive
。如果执行doSomethingIntensive
花费超过1秒钟会发生什么?在您的情况下,doSomethingIntensive
将是“下载图像并显示它”。如果连接速度较慢,则绝对有可能花费超过1秒的时间。
现在考虑
function doSomethingIntensive() {
...
setTimeout(doSomethingIntensive, 1000)
}
setTimeout(doSomethingIntensive, 1000) // or just doSomethingIntensive() if you don't want the initial wait
此代码完整地执行强化操作,然后 将强化功能的新调用排队。您最终会获得更加一致的行为。
一个不错的技巧是利用“虚拟”图像下载该图像,然后再将其应用于真实dom元素-利用浏览器缓存。
const images = ["https://via.placeholder.com/150", "https://via.placeholder.com/150x50", "https://via.placeholder.com/150x100", "https://via.placeholder.com/150x25"]
const image = document.querySelector('#image')
let currentImage = 0
const vImage = new Image()
function updateImage() {
// choose the next image
const newImageSrc = images[currentImage++ % images.length]
vImage.onload = function() {
image.src = newImageSrc
/* this should be instant but it's still good
* practice to always use the onload event handler */
image.onload = function () {
setTimeout(updateImage, 1000)
}
}
vImage.src = newImageSrc
}
updateImage()
<img id="image">
打开浏览器的开发工具并启用连接限制。第一张图像可能需要一段时间才能显示,但是您永远不会显示空白(无)图像。 ...虽然这可能超出了您的需求。
答案 1 :(得分:0)
您想使用setTimeout,这将在x milliseconds
中运行一个函数。
const images = ["https://via.placeholder.com/150", "https://via.placeholder.com/150x50", "https://via.placeholder.com/150x100", "https://via.placeholder.com/150x25"]
// Get the image reference
const img = document.querySelector('#my-image')
// Add an event to listen for when it loads and trigger the next change
img.onload = () => setTimeout(changeImage, 1000)
// A counter to count the times we change images
let counter = 0
function changeImage() {
// Set the image src
// We will get the modulus value
// Using this the number will never be larger than the length
img.src = images[counter++ % images.length]
}
changeImage()
<img id="my-image">
(由geuis添加)setInterval的替代示例,因为发问者可能对js没有很高的了解:
let counter = 0
setInterval(() => {
img.src = images[counter % images.length];
counter++;
}, 1000);