使用 display:none 在 Chrome 上重置 GIF 动画的正确方法 [英] Proper way to reset a GIF animation with display:none on Chrome

查看:46
本文介绍了使用 display:none 在 Chrome 上重置 GIF 动画的正确方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

标题不言自明,但我将提供有关此问题的分步视图.希望我不是第一个在 Webkit/Chrome 上注意到这个(显然)错误的人.

我想重置 GIF 动画.到目前为止,我看到的所有示例要么简单地将图像的 src 设置为自身,要么将其设置为空字符串,然后再次将原始 src 设置为空字符串.

看看这个 JSFiddle 以供参考.GIF 在 IE、Firefox 和 Chrome 上重置得非常好.

我遇到的问题是当图像在 仅 Google Chrome 上具有 display:none 时.

检查这个JSFiddle.GIF 在 IE 和 Firefox 上显示在页面中之前可以正常重置,但 Chrome 只是拒绝重置其动画!

到目前为止我尝试过的:

  • 在 Fiddle 中将 src 设置为自身,在 Chrome 中不起作用.
  • src 设置为空字符串并将其恢复为默认值也不起作用.
  • 在图像周围放置一个包装器,通过 .html('') 清空容器并将图像放回其中,这也不起作用.
  • 在设置 src 之前通过 .show().fadeIn() 更改图像的 display代码> 也不起作用.

目前我发现的唯一解决方法是将图像保持在默认的display 并通过.animate() 对其进行操作ing 和 .css() 模拟 display:none 行为所必需的不透明度、高度和可见性.

这个问题的主要原因(上下文)是我想在页面中淡入淡出之前重置 ajax 加载器 GIF.

所以我的问题是,是否有一种正确的方法来重置 GIF 图像的动画(避免 Chrome 的 display:none错误")或者它实际上是一个错误?

(ps.您可以更改小提琴中的 GIF 以获得更合适/更长的动画 gif 以进行测试)

解决方案

Chrome 处理样式更改的方式与其他浏览器不同.

在 Chrome 中,当您不带参数调用 .show() 时,该元素实际上不会立即显示在您调用它的地方.取而代之的是,Chrome排队新样式的应用程序在评估当前的 JavaScript 块之后执行;而其他浏览器会立即应用新的样式更改.但是,.attr() 不会排队.因此,当元素根据 Chrome 仍然不可见时,您正在有效地尝试设置 src,并且当原始 src 和新 src 是一样的.

相反,您需要做的是确保 jQuery 设置 src after display:block 应用.你可以利用setTimeout来达到这个效果:

var src = 'http://i.imgur.com/JfkmXjG.gif';$(document).ready(function(){var $img = $('img');$('#target').toggle(功能(){无功超时= 0;//没有延迟$img.show();设置超时(函数(){$img.attr('src', src);}, 暂停);},功能(){$img.hide();});});

这确保了 src display:block 被应用到元素之后被设置.

这样做的原因是因为 setTimeout 将函数排队等待 later 执行(不管 later 有多长),所以函数不再被认为是当前函数的一部分JavaScript 的块",它为 Chrome 先呈现和应用 display:block 提供了一个间隙,从而使元素在其 src 属性设置之前可见.

演示:http://jsfiddle.net/F8Q44/19/

感谢 freenode IRC 的 #jquery 中的 shoky 提供了一个更简单的答案.

<小时>

或者,您可以强制重绘以刷新批量样式更改.例如,这可以通过访问元素的 offsetHeight 属性来完成:

$('img').show().each(function() {this.offsetHeight;}).prop('src', '图片src');

演示:http://jsfiddle.net/F8Q44/266/

Title is self-explanatory, but I'll provide a step-by-step view on the matter. Hopefully I'm not the first one to have noticed this (apparently) bug on Webkit/Chrome.

I want to reset a GIF animation. All of the examples I've seen so far either simply set the src of the image to itself or set it to an empty string followed by the original src again.

Take a look at this JSFiddle for reference. The GIF resets perfectly fine on IE, Firefox and Chrome.

The issue which I have is when the image has display:none on Google Chrome only.

Check this JSFiddle. The GIF resets fine on IE and Firefox before being displayed in the page, but Chrome simply refuses to reset its animation!

What I've tried so far:

  • Setting the src to itself as in Fiddle, doesn't work in Chrome.
  • Setting the src to an empty string and restoring it to the default, doesn't work either.
  • Putting an wrapper around the image, emptying the container through .html('') and putting the image back inside of it, doesn't work either.
  • Changing the display of the image through .show() or .fadeIn() right before setting the src doesn't work either.

The only workaround which I've found so far is keeping the image with its default display and manipulating it through .animate()ing and .css()ing the opacity, height and visibility when necessary to simulate a display:none behaviour.

The main reason (context) of this question is that I wanted to reset an ajax loader GIF right before fading it in the page.

So my question is, is there a proper way to reset a GIF image's animation (which avoids Chrome's display:none "bug") or is it actually a bug?

(ps. You may change the GIF in the fiddles for a more appropriate/longer animation gif for testing)

解决方案

Chrome deals with style changes differently than other browsers.

In Chrome, when you call .show() with no argument, the element is not actually shown immediately right where you call it. Instead, Chrome queues the application of the new style for execution after evaluating the current chunk of JavaScript; whereas other browsers would apply the new style change immediately. .attr(), however, does not get queued. So you are effectively trying to set the src when the element is still not visible according to Chrome, and Chrome won't do anything about it when the original src and new src are the same.

Instead, what you need to do is to make sure jQuery sets the src after display:block is applied. You can make use of setTimeout to achieve this effect:

var src = 'http://i.imgur.com/JfkmXjG.gif';
$(document).ready(function(){
    var $img = $('img');
    $('#target').toggle(
        function(){
            var timeout = 0; // no delay
            $img.show();
            setTimeout(function() {
                $img.attr('src', src);
            }, timeout);
        },
        function(){
            $img.hide();
        }
    );
});

This ensures that src is set after display:block has been applied to the element.

The reason this works is because setTimeout queues the function for execution later (however long later is), so the function is no longer considered to be part of the current "chunk" of JavaScript, and it provides a gap for Chrome to render and apply the display:block first, thus making the element visible before its src attribute is set.

Demo: http://jsfiddle.net/F8Q44/19/

Thanks to shoky in #jquery of freenode IRC for providing a simpler answer.


Alternatively, you can force a redraw to flush the batched style changes. This can be done, for example, by accessing the element's offsetHeight property:

$('img').show().each(function() {
    this.offsetHeight;
}).prop('src', 'image src');

Demo: http://jsfiddle.net/F8Q44/266/

这篇关于使用 display:none 在 Chrome 上重置 GIF 动画的正确方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆