JavaScript - просматривайте массив каталогов изображений и применяйте их к изображению - PullRequest
0 голосов
/ 03 мая 2019

У меня есть массив, содержащий несколько значений, каждое из которых является местоположением изображения на веб-сайте.

["img/image1.png", "img/image2.png", "img/image3.png", "img/image4.png"]

Мне нужно просмотреть их и применить их как атрибут src кimage последовательно каждую секунду, image1, затем image2, image3 и т. д. Я действительно хочу использовать цикл for, но я совершенно не знаю, с чего начать ...

Ответы [ 2 ]

2 голосов
/ 04 мая 2019

Я не думаю, что цикл 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 с циклом самоссылки.

1020 * рассмотреть *

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

Этот код полностью выполняет интенсивную операцию , а затем ставит в очередь новый вызов интенсивной функции. Вы в конечном итоге с гораздо более последовательным поведением.

хитрый трюк заключается в том, чтобы использовать «виртуальное» изображение для загрузки изображения перед его применением к элементу real 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">

Откройте инструменты разработчика вашего браузера и включите регулирование соединения. Первое изображение может появиться некоторое время, но вы никогда не увидите пустое (нет) изображение. ... хотя это может быть за то, что вам нужно для этого.

0 голосов
/ 04 мая 2019

Вы хотели бы использовать 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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...