使用 display:none 在 Chrome 上重置 GIF 动画的正确方法 [英] Proper way to reset a GIF animation with display:none on Chrome
问题描述
标题不言自明,但我将提供有关此问题的分步视图.希望我不是第一个在 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 thesrc
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屋!