加载完成后淡入图片

14

我找到了这段代码来实现所需的效果,并在JSFiddle上尝试了一下:

http://jsfiddle.net/AndyMP/7F9tY/366/

它似乎能够按照预期工作,即在图片加载完成后淡入。然后我在网页中尝试了一下,但它并没有像同样的方式工作,而是先加载图片而不是淡入。虽然有时它看起来像是在同时加载和淡入。

如果可能的话,有没有更可靠的方法来实现这个效果,最好是通过修改这段代码来实现?

$("#image").ready(function(){ $("#preload").fadeIn(1000); });

7个回答

45

在你的实际HTML标记中,唯一可靠的方法来执行fadeIn()一个图片是在HTML标记中设置一个onload处理程序,像这样:

<div id="image">
    <img id="preload" onload="fadeIn(this)" src="https://photos.smugmug.com/photos/i-NLws86p/0/b356e43a/L/i-NLws86p-S.jpg" style="display:none;" />
</div>

<script>
// this function must be defined in the global scope
window.fadeIn = function(obj) {
    $(obj).fadeIn(1000);
}
</script>

这里有一个工作演示:https://jsfiddle.net/jfriend00/X82zY/

这种方法的好处是您不需要给每个图像设置ID或类。只需在标记中设置样式和事件处理程序即可。

之所以必须将事件处理程序放在标记中,是因为如果等到页面上的JavaScript运行时再添加事件处理程序,则可能为时已晚。图像可能已经加载完成(特别是如果它在浏览器缓存中),因此您可能会错过 onload 事件。如果您将处理程序放置在HTML标记中,则不会错过 onload 事件,因为处理程序在图像开始加载之前就被分配了。

如果您不想将事件处理程序放在JavaScript中,则可以像这样使用占位符来实现:在实际HTML中使用占位符并使用JavaScript创建实际的图像标签并插入它们,并从占位符中获取图像URL:

<div>
    <span class="fadeIn" data-src="https://photos.smugmug.com/photos/i-NLws86p/0/b356e43a/L/i-NLws86p-S.jpg"></span>
</div>

<script>
$(document).ready(function() {
    $(".fadeIn").each(function() {
        var src = $(this).data("src");
        if (src) {
            var img = new Image();
            img.style.display = "none";
            img.onload = function() {
                $(this).fadeIn(1000);
            };
            $(this).append(img);            
            img.src = src;
        }
    });
});
</script>

工作演示:https://jsfiddle.net/jfriend00/BNFqM/

第一个选项可以更快地加载您的图像(因为图像加载在页面解析时立即开始),但第二个选项可以让您对该过程具有更多的程序控制权。


2
@Andy - 这很奇怪。选项1与其他jQuery无关。其他jQuery仍将放置在$(document).ready()函数中。我很高兴选项2适用于您,但如果您想找出为什么其他事情不起作用,选项1也可以。 - jfriend00
1
@ethan22 - 在 JavaScript 运行之前,它可能会在加载时短暂地闪现可见。 - jfriend00
1
@Ethan - 然后你可以使用 this.style.display = "inline"; 在普通的 JavaScript 中使其可见。 - jfriend00
1
@Skipjack - 已修复。 - jfriend00
@AdamHunterPeck - 使用哪个浏览器? - jfriend00
显示剩余12条评论

13

纯JavaScript和CSS解决方案:

使用opacity的过渡效果。

const images = document.getElementsByTagName("img");
for (let image of images) {
  image.addEventListener("load", fadeImg);
  image.style.opacity = "0";
}

function fadeImg () {
  this.style.transition = "opacity 2s";
  this.style.opacity = "1";
}
<img src="https://upload.wikimedia.org/wikipedia/commons/6/62/Lunch_atop_a_Skyscraper.jpg" width="190">
<img src="https://upload.wikimedia.org/wikipedia/en/7/7d/Lenna_%28test_image%29.png" width="190">
<img src="https://upload.wikimedia.org/wikipedia/commons/2/21/Mandel_zoom_00_mandelbrot_set.jpg" width="190">


好的方法。只需记住,在IE9或更低版本中,CSS过渡效果无法正常工作。 - tweray
这仍然依赖于“load”。 - sheriffderek

4

html

<div id="image">
    <img id="preload" src="http://farm8.staticflickr.com/7227/7007769551_3b5b1640ea_b.jpg" style="display:none;" />
</div>

Javascript

.ready()方法不是按照你想象中的方式触发的,请参见"load" jQuery事件处理程序。

$("#preload").load(function(evt){
      $(this).fadeIn(1000);
});

请密切注意文档中下方有关.load()的限制。 - DefyGravity
这可能在某些浏览器中无法正常工作,因为图片在浏览器缓存中后,图片将在 JavaScript 运行之前完成加载,因此您永远看不到加载事件。 - jfriend00
@jfriend00 是的,这在.load()的文档中有说明。 - DefyGravity

4

如果您是使用angular.js的人,以下内容可能会对您有所帮助:

我编写了一个小指令,可以很好地完成这项工作。

JS代码:

.directive('imgFadeInOnload', function () {
    return {
      restrict: 'A',
      link: function postLink(scope, element, attr) {
        element.css('opacity', 0);
        element.css('-moz-transition', 'opacity 2s');
        element.css('-webkit-transition', 'opacity 2s');
        element.css('-o-transition', 'opacity 2s');
        element.css('transition', 'opacity 2s');
        element.bind("load", function () {
          element.css('opacity', 1);
        });
        element.attr('src', attr.imgFadeInOnload);
      }
    };
  });

HTML:

<img img-fade-in-onload="{{imgSrc}}" src="">

通过在指令代码中设置src而不是在HTML中设置,可以解决jfriend00提到的问题(处理程序在onload触发后附加)。

我打算尝试使用angular.js - 谢谢您的发布。 - Andy
使用Angular时的最佳解决方案。太棒了! - Neel

1
这是一个基于@jfriend00答案的css过渡和javascript解决方案,类似于@Robbendebiene的方法:
  • 如果js被关闭,则提供显示图像的回退
  • 只需要一个内联javascript代码onload="this.style.opacity=1"
  • 所有动画都是CSS,不需要jQuery或复杂的javascript

img.fadein {
  opacity: 1;  /* fallback in case of no js */
  transition: opacity 500ms ease;
  max-width: 100%;
  height: auto;
}
.js img.fadein {
  opacity: 0; /* start with hidden image if we have js */
}
<!-- use moderinr to provide the "js" class on the html element -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/modernizr/2.8.3/modernizr.min.js"></script>
<img class="fadein" onload="this.style.opacity=1" src="http://lorempixel.com/1500/1500/">


1

我该如何让它适用于同一页上的多个图像?我不想重复相同的代码并为每个图像分配单独的ID,否则似乎只有第一个图像会加载。 - Andy
这可能在某些浏览器中无法正常工作,因为图片在浏览器缓存中后,图片将在 JavaScript 运行之前完成加载,因此您永远看不到加载事件。 - jfriend00

0

对于那些想要寻找现代紧凑、无需JQuery的版本并且八年后依然存在(像我一样)。如果下面插入的代码没有正确渲染,请尝试下面的fiddle,它可以正常工作。

fiddle链接:http://jsfiddle.net/s6nvb95z/

fadeIn = e => e.style.opacity = 1;
img {
   width: 500px; // Just for this example
   opacity: 0;
   transition: opacity .2s ease-out;
}
<div id="image">
    <img onload="fadeIn(this)" src="https://live.staticflickr.com/4672/39593615781_fe8e95a6fb_k.jpg" />
</div>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接