Перебор массива изображений и разрывы цикла с отсутствующим изображением

#javascript #jquery #arrays

#javascript #jquery #массивы

Вопрос:

У меня есть массив URL-адресов изображений, и я просматриваю их каждый раз, когда пользователь нажимает кнопку «далее». Однако этот цикл прерывается, когда он сталкивается с отсутствующим изображением. Есть идеи, как цикл может продолжаться? Я заменяю отсутствующее изображение статическим, используя функцию ошибки jQuery. Цикл отлично работает без пропущенных изображений… Он просто останавливается, когда обнаруживает ошибку 404.

Это пример моего кода:

 var $img = $(".testImg") 
for(var i = 0; i < imgUrls.length;i  ) {
    if(imgUrls[i] == $img.attr("src")) {
      if(i === (imgUrls.length-1)) {
        $img.attr("src",imgUrls[0]).error(function(){
          $(this).attr('src', 'images/missing.png')
        })
        break
      }
      $img.attr("src",imgUrls[i 1]).error(function(){
        $(this).attr('src', 'images/missing.png')
      })
      break
  }
}
  

РЕШЕНИЕ (спасибо Хосе ниже):

 var $img = $("#vImg") 
      $img.show()
      $("#missingImg").hide()
      for(var i = 0; i < imgUrls.length;i  ) {
        if(imgUrls[i] == $img.attr("src")) {
          if(i === (imgUrls.length-1)) {
            $img.error(function(){
              $("#vImg").hide()
              $("#missingImg").show()
            }).attr("src",imgUrls[0])
            break
          }
          $img.error(function(){
            $("#vImg").hide()
            $("#missingImg").show()
          }).attr("src",imgUrls[i 1])
          break
        }
      }
  

Я уверен, что мой код мог бы быть немного аккуратнее, хотя … 😉

Комментарии:

1. Он прерывается, потому что вы используете break ключевое слово.

2. замените break на continue

3. что вы имеете в виду под «отсутствующим изображением»? в массиве у вас есть пустая строка вместо src?

4. break Ключевое слово @Scimonster не является причиной . Это attr выполняется только один раз. Он использует break только как оптимизацию цикла, поскольку нет необходимости завершать цикл, когда он находит текущий url ( if(imgUrls[i] == $img.attr("src")) ) .

5. Извините, чтобы уточнить… Мой массив изображений состоит из абсолютных URL-адресов. Я ввел URL-адрес, который, как я знаю, не имеет изображения для тестирования. Если я заменяю break на continue, цикл перестает работать все вместе. Возможно, мне нужно переосмыслить, как я это делаю.

Ответ №1:

Вы определяете error обработчик после установки URL-адреса, что неверно.

Когда вы делаете это:

 $img.attr("src", "someInvalidURL.png").error(yourErrorHandler)
  

yourErrorHandler никогда не вызывается в случае 404 (или любой другой ошибки), потому что вы регистрируете error обработчик после изменения атрибута src .

Сначала вам нужно зарегистрировать error событие и только затем выполнить запрос (изменить src ).

 $img.error(yourErrorHandlerThatWorks).attr("src", "someInvalidURL.png")
  

Кроме того, каждый раз, когда вы нажимаете кнопку «Далее», вы повторно регистрируете error событие. Вы можете и должны зарегистрироваться только один раз:

 $(".testImg").error(function() {
      $(this).attr('src', 'images/missing.png')
});
  

и тогда ваш следующий код кнопки может быть:

 for(var i = 0; i < imgUrls.length;i  ) {
    if(imgUrls[i] == $img.attr("src")) {
      if(i === (imgUrls.length-1)) {
        $img.attr("src",imgUrls[0])
        break
      }

      $img.attr("src",imgUrls[i 1])
      break
  }
}
  

Редактировать:

Теперь я понимаю, почему ваша следующая кнопка перестает работать.

При возникновении ошибки вы устанавливаете URL-адрес $img images/missing.png равным . Тогда, очевидно, кнопка «Далее» никогда ничего не сделает, потому что условие imgUrls[i] == $img.attr("src") всегда будет ложным (это условие будет работать как imgUrls[i] == "images/missing.png" .

Вам нужно сделать что-то еще в обработчике ошибок, например, использовать другое <img> с отсутствующим изображением, которое всегда скрыто и появляется только при возникновении ошибки.

Комментарии:

1. Отлично — вот и все! Большое спасибо. На самом деле очевидно! Иногда, когда вы слишком долго смотрите на вещи … 😉

Ответ №2:

Выбросьте свои break -операторы и используйте вместо них правильный if else cascade, например:

 var $img = $(".testImg");
for (var i = 0; i < imgUrls.length; i  ) {
    if (imgUrls[i] == $img.attr("src")) {
        if (i === (imgUrls.length - 1)) {
            $img.attr("src", imgUrls[0]).error(function () {
                $(this).attr('src', 'images/missing.png');
            });
        } else {
            $img.attr("src", imgUrls[i   1]).error(function () {
                $(this).attr('src', 'images/missing.png');
            });
        }
    }
}
  

Таким образом, цикл выполняется до конца и не останавливается между ними..

если вы настаиваете на использовании своего кода, вам необходимо удалить последний break оператор, поскольку он останавливает for цикл, если URL-адрес не указан. Первый должен быть в порядке, если цикл может быть остановлен, если URL-адрес найден, но, честно говоря, я думаю, что мое предложение немного чище, хотя это звучит немного высокомерно 😉

Комментарии:

1. Спасибо, но мне нужно показывать только одно изображение за раз. Я должен был быть более ясным. Мой код находится внутри функции, которая запускается каждый раз, когда пользователь нажимает следующую кнопку. При нажатии на кнопку далее отображается следующее изображение в массиве. Когда он сталкивается с отсутствующим изображением, он корректно отображает отсутствующий файл.png, но затем следующая кнопка перестает работать…