54

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

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

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

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

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

复杂的因素是我事先不知道图像的高度和宽度:它们是响应式的,并且只是设置为width: 100%包含 div。这是 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 答案。还是我事先不知道图像的高度是一个无法克服的问题?我确实知道图像的纵横比。

4

11 回答 11

32

不要直接引用图像,而是将其粘贴在 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');
}
于 2013-05-13T08:53:10.780 回答
28

请记住 - 建议使用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>

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

于 2018-07-02T10:26:10.960 回答
13

在开始研究延迟加载和其他 JavaScript 之前,有一件非常简单的事情需要检查。确保您正在加载的 JPEG 图像在启用“渐进式”选项的情况下保存!

这将导致他们迭代地加载图像,从低分辨率且下载速度更快的占位符开始,而不是在渲染之前等待最高分辨率的数据。

于 2016-05-23T12:54:24.010 回答
4

随意复制这个:

<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>

我从这里得到这个:预加载器会继续加载,并且在加载内容时不会消失

于 2020-10-22T17:38:54.147 回答
3

这很简单...

此方案允许加载默认为占位符图像的个人资料照片。

您可以将多个 CSS 背景图像加载到一个元素中。当头像照片失败时,占位符图像默认显示为 div。

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

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

在此处输入图像描述

于 2018-06-25T17:29:37.940 回答
2

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

于 2013-02-07T10:33:41.267 回答
2

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

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>

于 2020-10-17T18:14:20.573 回答
2

这是一种天真的方法,

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

您可以操纵这些值,但它会在图像周围创建一个非常浅的边框,不会推送内容。图像可以在他们想要的任何时间加载,您可以获得良好的用户体验。

于 2016-08-18T16:27:56.373 回答
0

您可以在开发者工具控制台中找到图像的宽度和高度,例如在 Chrome 中,您可以单击开发者工具控制台中的光标图标,当您将鼠标悬停在页面上时,它将突出显示页面中元素的所有属性.

这将帮助您找到图像的宽度和高度,因为如果您将鼠标悬停在图像顶部,它将为您提供图像的尺寸和其他更多属性。您还可以为每个图像制作一个单独的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位于图像下方,因此当图像无法加载时,用户将看到灰色.belowdiv。您看不到.belowdiv,因为它隐藏在图像下方。您唯一会看到这种情况的是图像加载延迟时。这将解决您的所有问题。

于 2020-10-20T20:03:56.923 回答
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>

于 2020-10-24T14:28:13.160 回答
0

这是我对Tailwind CSS所做的,但它只是 CSS:

img {
  @apply bg-no-repeat bg-center;

  body.locale-en & {
    background-image: url("data:image/svg+xml;utf8,<svg width='100' height='100' viewBox='0 0 100 100' xmlns='http://www.w3.org/2000/svg'><text x='50%' y='50%' style='font-family: sans-serif; font-size: 12px;' dominant-baseline='middle' text-anchor='middle'>Loading…&lt;/text></svg>");
  }

  body.locale-fr & {
    background-image: url("data:image/svg+xml;utf8,<svg width='100' height='100' viewBox='0 0 100 100' xmlns='http://www.w3.org/2000/svg'><text x='50%' y='50%' style='font-family: sans-serif; font-size: 12px;' dominant-baseline='middle' text-anchor='middle'>Chargement…&lt;/text></svg>");
  }
}
于 2022-01-18T07:25:35.653 回答