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>
мне в основном нужно иметь возможность исчезать в
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; }
}