占位符背景/图像在等待加载完整图像?

时间:2013-02-07 10:23:20

标签: css

我的页面上有几张图片。我发现页面在图像加载之前开始渲染(这很好),但视觉效果并不好。最初,用户会看到:

 --------hr--------
 text

然后几毫秒后页面跳转显示:

--------hr--------
[           ]
[   image   ]
[           ]
text

是否有一种简单的方法可以显示图像占据的完全是宽度和高度的灰色背景图像,直到图像本身加载?

复杂因素是我不知道图像的高度和宽度:它们是响应的,只是设置为包含div的width: 100%。这是HTML / CSS:

<div class="thumbnail">
<img src="myimage.jpeg" />
<div class="caption">caption</div>
</div>
img { width: 100% } 

这是一个JSFiddle来说明基本问题:http://jsfiddle.net/X8rTB/3/

我已经研究了LazyLoad之类的东西,但我不禁觉得必须有一个更简单,非JS的答案。或者事实上,我事先不知道图像的高度是一个难以克服的问题?我知道图像的纵横比。

11 个答案:

答案 0 :(得分:18)

不要直接引用图像,而是将其粘贴在DIV中,如下所示:

<div class="placeholder">
    <div class="myimage" style="background-image: url({somedynamicimageurl})"><img /></div>
</div>

然后在你的CSS中:

.placeholder {
    width: 300;
    height: 300;
    background-repeat: no-repeat;
    background-size: contain;
    background-image: url('my_placeholder.png');
}

答案 1 :(得分:4)

在开始研究延迟加载和其他JS之前,有一个非常简单的事情需要检查。 确保您加载的JPG图像使用&#39; progressive&#39;保存。选项已启用! 这将导致它们迭代加载图像,从低分辨率和更快下载的占位符开始,而不是在渲染之前等待最高的res数据。

答案 2 :(得分:3)

请记住-上面建议使用div背景方法的答案将通过将图像从img转换为div背景来更改图像的语义。这将导致诸如搜索爬虫无法为这些图像建立索引,浏览器延迟加载这些图像(除非您明确地预加载它们)之类的事情。

此问题的一种解决方案(虽然不使用div背景方法)是为您的图像添加一个包装div,然后根据您需要事先知道的图像的纵横比为其添加padding-top。以下代码适用于宽高比为2:1(高度为宽度的50%)的图像

<div style="width:100%;height:0; padding-top:50%;position:relative;">
  <img  src="<imgUrl>" style="position:absolute; top:0; left:0; width:100%;">
</div>

当然-这种方法的主要缺点是您需要事先知道图像的纵横比。

答案 3 :(得分:2)

我希望这行得通。 随时复制:

<script>
    window.addEventListener("load", function () {
        document.getElementById('image').style.backgroundColor = 'transparent';
    });
</script>

<body>
       <image src="example.example.example" alt="example" id="image" style="background-color:blue;">
</body>

我从这里得到的:Preloader keeps on loading and doesnt disappear when the content is loaded

答案 4 :(得分:1)

我唯一可以想到的是,尽量减少对文字的跳跃效果,将min-height设置为图像的显示位置,我会说 - 将其设置为您知道的“较短”图像。这样跳转就不那么明显了,你不需要使用lazyLoad ......但是它并没有完全解决你的问题。

答案 5 :(得分:1)

这是一种天真的做法,

  

img {   box-shadow:0 0 10px 0 rgba(#000,0.1);   }

您可以操纵这些值,但它的作用是在图像周围创建一个非常轻的边框,不会推动内容。图像可以随时加载,您可以获得良好的用户体验。

希望它有所帮助

答案 6 :(得分:1)

这很简单.. 这种情况下可以加载该默认占位符图像的个人资料照片。 您可以将多个CSS背景图像加载到一个元素中。当头像照片失败时,占位符图像将显示为默认div。

如果您使用的是通过CSS背景图片加载的div元素,则可以使用以下样式:

#avatarImage {
    background-image: url("place-holder-image.png"), url("avatar-image.png");
}
<div id="avatarImage"></div>

enter image description here

答案 7 :(得分:1)

除了已经提到的所有解决方案之外,最后一个解决方案是在未加载所有内容的情况下隐藏文档。

window.addEventListener('load', (e) => {
  document.body.classList.add('loaded');
});
body {
  opacity: 0;
}
body.loaded {
  opacity: 1;
}
<div id="sidebar">
  <img src="http://farm9.staticflickr.com/8075/8449869813_1e62a60f01_b.jpg" />
  <img src="https://www.nla.gov.au/sites/default/files/pic-1.jpg" />
  <img src="https://www.nla.gov.au/sites/default/files/pic-2.jpg" />
  <img src="https://www.nla.gov.au/sites/default/files/pic-3.jpg" />
  <img src="https://www.nla.gov.au/sites/default/files/pic-4.jpg" />
  <img src="https://www.nla.gov.au/sites/default/files/pic-5.jpg" />
  <img src="https://www.nla.gov.au/sites/default/files/pic-6.jpg" />
</div>

或在加载所有内容时显示一些动画:

window.addEventListener('load', (e) => {
  document.body.classList.add('loaded');
});
.loader {
  border: 16px solid #f3f3f3;
  border-radius: 50%;
  border-top: 16px solid #3498db;
  width: 70px;
  height: 70px;
  -webkit-animation: spin 2s linear infinite;
  /* Safari */
  animation: spin 2s linear infinite;
  position: absolute;
  left: calc(50% - 35px);
  top: calc(50% - 35px);
}

@keyframes spin {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

body :not(.loader) {
  opacity: 0;
}

body .loader {
  display: block;
}

body.loaded :not(.loader) {
  opacity: 1;
}

body.loaded .loader {
  display: none;
}
<div class="loader"></div>
<div id="sidebar">
  <img src="http://farm9.staticflickr.com/8075/8449869813_1e62a60f01_b.jpg" />
  <img src="https://www.nla.gov.au/sites/default/files/pic-1.jpg" />
  <img src="https://www.nla.gov.au/sites/default/files/pic-2.jpg" />
  <img src="https://www.nla.gov.au/sites/default/files/pic-3.jpg" />
  <img src="https://www.nla.gov.au/sites/default/files/pic-4.jpg" />
  <img src="https://www.nla.gov.au/sites/default/files/pic-5.jpg" />
  <img src="https://www.nla.gov.au/sites/default/files/pic-6.jpg" />
</div>

答案 8 :(得分:0)

#avatarImage {
    background-image: url("place-holder-image.png"), url("avatar-image.png");
}
<div id="avatarImage"></div>

答案 9 :(得分:0)

您可以在devtools控制台中找到图像的宽度和高度,例如在chrome中,您可以单击devtools控制台中的光标图标,当您将鼠标悬停在页面上时,它将突出显示页面中元素的所有属性。页。这将帮助您找到图像的宽度和高度,因为如果将鼠标悬停在图像上方,它将为您提供图像的尺寸和其他更多属性。您还可以为每个图像制作一个单独的div,并使div相对于图像的宽度和高度。您可以这样做:

主div将包含图像以及图像下方的背景div。

HTML:

<html>
  <head>
     <meta charset="utf-8">
  </head>
  <body>
      <div class=".mainDiv">
        <div class="below"></div>
        <img src="https://imgix.bustle.com/uploads/image/2020/2/13/da1a1ca4-95ec-40ea-83c1-4f07fac8b9b7-eqb9xdwx0auhotc.jpg" width="500"/>
       </div>
  </body>
</html>

CSS:

.mainDiv {
  position: relative;
}

.below {
  position: absolute;
  background: #96a0aa;
  width: 500px;
  height: 281px;
}

img {
  position: absolute;
}

结果将是.below将位于图像下方,因此,当图像加载失败时,用户将看到灰色的.below div。您看不到.below div,因为它隐藏在图像下方。唯一的机会是延迟加载图像,这将解决您所有的问题。

答案 10 :(得分:0)

我有办法。但是您将需要使用javascript。

HTML:

img = document.getElementById("img")
text = document.getElementById("text")
document.addEventListener("DOMContentLoaded", () => {
    img.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOEAAADhCAMAAAAJbSJIAAAAA1BMVEWIiIhYZW6zAAAASElEQVR4nO3BgQAAAADDoPlTX+AIVQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADwDcaiAAFXD1ujAAAAAElFTkSuQmCC";
    text.innerHTML = "Loaded but image is not";
  });
window.onload = function() { 
img.src = "https://media.geeksforgeeks.org/wp-content/uploads/20190913002133/body-onload-console.png";
text.innerHTML = "Image is now loaded";
  };
#img {
    width: 400px;
    height: 300px;
}
<hr>

<img id="img" src="https://media.geeksforgeeks.org/wp-content/uploads/20190913002133/body-onload-console.png">

<p>Here is the Image</p>
<p id="text">Not Loaded</p>