Fade in background-image после загрузки (без jquery) при использовании медиа-запросов для замены изображений для разных размеров экрана

я читал всю ночь и, кажется, не могу прийти к какому-либо конкретному ответу на то, что лучший способ сделать это. Две вещи, которые я знаю do работы таковы:

для выцветания изображения при загрузке:

используйте обертку изображения и <img> тег, как это:

<div class="imageWrapper">
    <img src="img.jpg" alt="" onload="imageLoaded(this)">
</div>

и css выглядит как

.imageWrapper {
  opacity: 0
}

.loaded {
  opacity: 1
}

а затем в вашем js-файле есть что-то вроде

var imageLoaded = (img) => {
    var imgWrapper = img.parentNode;
    imgWrapper.className += ' loaded';
}

для загрузки a различное изображение на основе размера экрана

@media screen only and (min-device-width: 0) and (max-device-width: 450px) {
  .backgroundImage {
    background: url('small_background_image.jpg');
  }
}

@media screen only and (min-device-width: 451px) and (max-device-width: 1024px) {
  .backgroundImage {
    background: url('medium_background_image.jpg');
  }
}

@media screen only and (min-device-width: 1025px) {
  .backgroundImage {
    background: url('large_background_image.jpg');
  }
}

Моя Проблема

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

есть хороший способ сделать это?

мое решение:

я закончил тем, что использовал вариацию guest271314 ' s ответ для того, чтобы загрузить правильное изображение. Это работает на всех последних версиях каждого браузера и очень легко реализуется.

во-первых, у меня есть встроенный скрипт, расположенный прямо под моим открытием <body> тег, так что если мой браузер медленно загружает мой JS-файл, он может загрузите изображения прямо сейчас.

<body>
    <script>
        function imageLoaded(img) {
            if ((" " + img.className + " ").indexOf(" "+'loaded'+" ") > -1 ) {
            return true;
            } else {
                img.className += ' loaded';
            }
        }
    </script>

и тогда у меня есть мой <picture> тег вот так:

<picture class="backgroundContainer">
    <source srcset="img-1024.jpg" media="(min-width: 0px) and (max-width:1024px)">
    <source srcset="img-1920.jpg" media="(min-width: 1025px) and (max-width: 1920px)">
    <source srcset="img-2560.jpg" media="(min-width: 1921px)">
    <img class="backgroundImage" onload="imageLoaded(this)" src="img-1920.jpg" alt="">
</picture>

и моя Сасс выглядит так:

@keyframes fadeIn
  0%
    opacity: 0
  100%
    opacity: 1

.backgroundContainer
  width: 100%
  height: 100%

.backgroundImage
  opacity: 0

.loaded
  opacity: 1
  animation: fadeIn 3s

и это позволяет браузеру (независимо от скорости), чтобы дождаться правильно-по размеру изображение выполняется загрузка, а затем исчезает в over 3s, с резервом, с помощью <img> тег для старых браузеров.

4 ответов


edit #2: обновленный скрипку прогресса: https://jsfiddle.net/c5hy0g8r/11

проблема все еще в том, что в медленных сетевых условиях, используя css свойство "content" по-прежнему будет загружаться кусками, как обычно делают изображения. Этот обычный метод onload= "imageLoaded (this)" не будет работать на img или изображение, которое имеет свое содержимое, генерируемое содержимым css: url ('img.в JPG') свойство.

вы можете использовать <picture> элемент, имеющий один или несколько <source> с элементами srcset атрибут установлен в Источник изображения, который должен отображаться в <img> когда соответствующие media атрибут, заданный для допустимого списка запросов мультимедиа, соответствует среде.

At onload событие <img> элемент, установить родительский элемент opacity to 0; используйте requestAnimationFrame() анимация opacity в элемент 0 to 1.

<!DOCTYPE html>
<html>

<head>
  <style>
    .imageWrapper {
      opacity: 0;
    }
  </style>
</head>

<body>

  <picture class="imageWrapper">
    <source srcset="http://lorempixel.com/50/50/technics" media="(min-width: 0px) and (max-width:150px)">
    <source srcset="http://lorempixel.com/50/50/city" media="(min-width: 151px) and (max-width: 300px)">
    <source srcset="http://lorempixel.com/50/50/nature" media="(min-width: 301px) and (max-width:450px)">
    <source srcset="http://lorempixel.com/50/50/sports" media="(min-width: 451px) and (max-width:600px)">
    <source srcset="http://lorempixel.com/50/50/animals" media="(min-width: 601px)">
    <img width="50px" height="50px" onload="imageLoaded(this)" src="null" alt="">
  </picture>
  <figcaption></figcaption>
    <script>
    const num = 1/60;
    var fx = null;
    var caption = document.querySelector("figcaption");
    var imageLoaded = (img) => {
      caption.innerHTML = "";
      cancelAnimationFrame(fx);
      var n = 0;
      var imgWrapper = img.parentNode;
      imgWrapper.style.opacity = 0;
      fx = requestAnimationFrame(function animate() {
        console.log(n);
        if (n < 1) {
          n += num;
          imgWrapper.style.opacity = n;
          fx = requestAnimationFrame(animate);
        } else {
          caption.innerHTML = img.currentSrc.slice(img.currentSrc.lastIndexOf("/") + 1);
          console.log("complete");
        }
      })
    }
  </script>
</body>
</html>

plnkr http://plnkr.co/edit/RWSc6J3kUUJPUZsrpagi?p=preview


мне в основном нужно иметь возможность исчезать в background-image когда он загружает или может изменить <img> тег src перед загрузкой в зависимости от размера экрана или сделайте что-то, что включает в себя оба эти вещи используют метод, о котором я не знаю.

можно использовать css content свойство со значением url() функция, имеющая URL изображения для отображения или изменения отображаемого источника изображения;css animation, @keyframes исчезать в background-image когда источник изображение загружается.

HTML-код

<picture class="backgroundImage"></picture>

в CSS

.backgroundImage {
  opacity: 0; /* set `opacity` to `0` */
  width: 50px;
  width: 50px;
  content: url(http://lorempixel.com/50/50/technics); /* set intial image */
  animation-name: fadein;
  animation-iteration-count: 1;
  animation-duration: 2500ms;
  animation-fill-mode: both;
}

@keyframes fadein {
  to {
    opacity: 1; /* fade in image */
  }
}
/* set media queries */
@media screen only and (min-device-width: 0) and (max-device-width: 450px) {
  .backgroundImage {
    opacity: 0; /* set `opacity` to `0` */
    content: url(http://lorempixel.com/50/50/cats); /* set image */
    animation-name: first;
  }
  @keyframes first {
    to {
      opacity: 1; /* fade in image */
    }
  }
}

@media screen only and (min-device-width: 451px) and (max-device-width: 1024px) {
  .backgroundImage {
    opacity: 0; /* set `opacity` to `0` */
    content: url(http://lorempixel.com/50/50/city); /* set image */
    animation-name: second;
  }
  @keyframes second {
    to {
      opacity: 1; /* fade in image */
    }
  }
}

@media screen only and (min-device-width: 1025px) {
  .backgroundImage {
    opacity: 0; /* set `opacity` to `0` */
    content: url(http://lorempixel.com/50/50/sports); /* set image */
    animation-name: third;
  }
  @keyframes third {
    to {
      opacity: 1; /* fade in image */
    }
  }
}

jsfiddle https://jsfiddle.net/yayd5Lma/3


вы должны использовать анимации css3 для этой цели.

@-webkit-keyframes fadeIn {
            0% {opacity: 0;}
            100% {opacity: 1;}
         }

         @keyframes fadeIn {
            0% {opacity: 0;}
            100% {opacity: 1;}
         }

         .fadeIn {
            -webkit-animation-name: fadeIn;
            animation-name: fadeIn;
         }

Я бы просто загрузил все изображения в моей разметке и назначил классы для медиа-запросов:

<div class="imageWrapper">
    <img class="small" src="img_small.jpg" onload="imageLoaded(this)">
    <img class="med" src="img_med.jpg" onload="imageLoaded(this)">
    <img class="large" src="img_large.jpg" onload="imageLoaded(this)">
</div>

затем использовать медиа-запросы, чтобы скрыть их по мере необходимости:

@media screen only and (min-device-width: 0) and (max-device-width: 450px) {
  .imageWrapper .large, .imageWrapper .medium { display: none; }
}

@media screen only and (min-device-width: 451px) and (max-device-width: 1024px) {
  .imageWrapper .large, .imageWrapper .small { display: none; }
}

@media screen only and (min-device-width: 1025px) {
  .imageWrapper .small, .imageWrapper .medium { display: none; }
}