是否可以重新启动用作background-image
的动画GIF?
考虑这个HTML:
<div id="face">
<div id="eyes"></eyes>
</div>
这种风格:
#eyes.blink {
background-image:url('blink.gif');
}
我希望每次将blink.gif
课程添加到blink
时都会播放#eyes
动画,而不仅仅是第一次。
我希望这可行:
function startBlink() {
$('#eyes').addClass('blink');
}
function stopBlink() {
$('#eyes').removeClass('blink');
}
问题是Firefox和WebKit浏览器一旦播放一次就不再播放背景图像GIF动画。添加/删除类闪烁仅适用于第一次。
答案 0 :(得分:17)
你可以通过重新加载动画gif来重播。这对于带宽来说并不理想,特别是如果您的图像很大,但它会强制重新启动动画。
在我的示例中,我添加并删除onclick
<div id="animated">
的{{1}}:
$('#animated').click(function() {
/* Reference to the clicked element and toggle the .go class */
var $div = $(this);
$div.toggleClass('go');
/* Start the animated gif */
if ($div.hasClass('go')) {
/* Create an <img> element and give it the animated gif as a src. To
force a reload we add a date parameter to the URL */
var img = document.createElement('img');
img.src = "http://yoursite.com/animated.gif?p" + new Date().getTime();
/* Once the image has loaded, set it as the background-image */
$(img).load(function(){
$div.css({backgroundImage: "url("+img.src+")"});
});
/* Remove the background-image */
} else {
$div.css({backgroundImage: "none"});
}
})
Demo of it正在行动中。
答案 1 :(得分:7)
我发现你还可以在图片src的末尾添加?+Math.random()
,然后重新加载.gif文件。
答案 2 :(得分:3)
我结合了解决方案的几个部分,制作了一个解决(希望)所有问题的整个解决方案:
background-image
)在我的解决方案中,我创建了辅助图像,这些图像被添加到正文中但隐藏在某种方式中,因此它们仍然由浏览器呈现,但不会使用position: absolute; left: -5000px;
在视觉上与页面交互。
我们的辅助图像的引用缓存在resetHelperImages
中,因此我们可以在后续调用中将它们重用于同一图像。
我正在使用jQuery作为我的例子,但它也可以适应没有jQuery的工作。
测试:Chrome(版本43.0.2357.130 m)
var resetHelperImages = {};
function restartAnimation(elem) {
elem = $(elem);
for (var i = 0; i < elem.length; i++) {
var element = elem[i];
// code part from: http://stackoverflow.com/a/14013171/1520422
var style = element.currentStyle || window.getComputedStyle(element, false);
// var bgImg = style.backgroundImage.slice(4, -1).replace(/"/g, '');
var bgImg = style.backgroundImage.match(/url\(([^\)]+)\)/)[1].replace(/"/g, '');
// edit: Suggestion from user71738 to handle background-images with additional settings
var helper = resetHelperImages[bgImg]; // we cache our image instances
if (!helper) {
helper = $('<img>')
.attr('src', bgImg)
.css({
position: 'absolute',
left: '-5000px'
}) // make it invisible, but still force the browser to render / load it
.appendTo('body')[0];
resetHelperImages[bgImg] = helper;
setTimeout(function() {
helper.src = bgImg;
}, 10);
// the first call does not seem to work immediately (like the rest, when called later)
// i tried different delays: 0 & 1 don't work. With 10 or 100 it was ok.
// But maybe it depends on the image download time.
} else {
// code part from: http://stackoverflow.com/a/21012986/1520422
helper.src = bgImg;
}
}
// force repaint - otherwise it has weird artefacts (in chrome at least)
// code part from: http://stackoverflow.com/a/29946331/1520422
elem.css("opacity", .99);
setTimeout(function() {
elem.css("opacity", 1);
}, 20);
}
.myBgImageClass {
background-image: url('http://i410.photobucket.com/albums/pp184/OllieMarchant/Countup.gif');
width: 100px;
height: 150px;
background-size: 100%;
background-repeat: no-repeat;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="myBgImageClass"></div>
<button onclick="restartAnimation($('.myBgImageClass'))">restart</button>
答案 3 :(得分:1)
您是否考虑使用两次相同的图像,名为blink.gif和blink2.gif,为它们添加两个类并在类之间切换?
<div id="face">
<div id="eyes"></eyes>
</div>
.blink {
background-image:url('blink.gif');
}
.blink2 {
background-image:url('blink2.gif');
}
function MakeBlink()
{
if ($('#eyes').hasClass('blink'))
{
$('#eyes').removeClass('blink').addClass('blink2');
} else
{
$('#eyes').removeClass('blink2').addClass('blink');
}
}
答案 4 :(得分:1)
仅仅因为我仍然需要这个时不时我想我使用的纯JS函数可能对其他人有帮助。这是一种重新启动动画gif的纯JS方式,无需重新加载。您可以通过链接和/或文档加载事件来调用它。
<img id="img3" src="../_Images/animated.gif">
<a onClick="resetGif('img3')">reset gif3</a>
<script type="text/javascript">
// reset an animated gif to start at first image without reloading it from server.
// Note: if you have the same image on the page more than ones, they all reset.
function resetGif(id) {
var img = document.getElementById(id);
var imageUrl = img.src;
img.src = "";
img.src = imageUrl;
};
</script>
在某些浏览器上,您只需要将img.src重置为自身,它就可以正常工作。在IE上,您需要在重置之前清除它。此resetGif()从图像ID中选择图像名称。如果您更改了给定ID的实际图像链接,这很方便,因为您不必记住更改resetGiF()调用。
- 尼科
答案 5 :(得分:1)
有一种替代方案,每次都不会重新加载GIF并浪费带宽。
它涉及将GIF作为Base64存储在内存中(绕过浏览器缓存),并使用FileReader API(似乎是supported in all modern browsers)。请注意,以这种方式加载图像需遵循跨源策略(与图像重新加载解决方案不同。)
更新:浏览器缓存在缓存背景图片数据URI方面越来越智能,导致动画无法重新开始。我发现我必须立即在数据网址中添加缓存清除随机字符串(根据DataURI Scheme,应该将其视为可选属性。在Chrome和IE Edge中测试。)
查看实际操作:http://jsfiddle.net/jcward/nknLrtzL/10/
以下是它的工作原理。此函数将图像加载为Base64编码的字符串。
function toDataUrl(url, callback) {
var xhr = new XMLHttpRequest();
xhr.onload = function() {
var reader = new FileReader();
reader.onloadend = function() {
callback(reader.result);
}
reader.readAsDataURL(xhr.response);
};
xhr.open('GET', url);
xhr.responseType = 'blob'; // IE11, set responseType must come after .open()
xhr.send();
}
然后,每当你想重新启动GIF动画时,将background-image
属性更改为none
,然后更改base64字符串(在某些浏览器中,您需要重新添加子项以触发更新没有setTimeout):
$div.css({backgroundImage: "none"});
$div.parent().add($div); // Some browsers need this to restart the anim
// Slip in a cache busting random number to the data URI attributes
$div.css({backgroundImage: "url("+img_base64.replace("image/gif","image/gif;rnd="+Math.random())+")"});
感谢toDataURL
protocol Subject {
func register(observer: Observer)
func remove(observer: Observer)
func notifyObservers()
}
protocol Observer {
func update(temperature: Double, humidity: Double, pressure: Double)
}
protocol DisplayElement {
func display()
}
class WeatherData: Subject {
var observers: [Observer]
var temperature: Double!
var humidity: Double!
var pressure: Double!
init() {
observers = []
}
func register(observer: Observer) {
observers.append(observer)
}
func remove(observer: Observer) {
}
func notifyObservers() {
for obs: Observer in observers {
obs.update(temperature: temperature, humidity: humidity, pressure: pressure)
}
}
}
函数(修复了IE11。)
答案 6 :(得分:0)
出于某种原因,这有效:
// Append the image to the page
var i = new Image();
i.src = 'some.gif';
document.body.appendChild(i);
// Now execute this line and the gif will restart
// (anywhere it appears on the page, including CSS backgrounds)
i.src = 'some.gif';
这需要将实际图像DOM元素附加到页面,但您可以使用visibility: hidden
隐藏它。此不要求图像通过网络多次下载。
我只在Firefox和Chrome中测试了这个。不确定其他浏览器。
答案 7 :(得分:0)
关于this answer发布的Frederic Leitenberger,我发现它工作得非常好。
但是,如果你的背景图片有多个分层的部分,它会崩溃,如下所示:
background-image: url(https://upload.wikimedia.org/wikipedia/commons/5/53/Google_%22G%22_Logo.svg),
radial-gradient(ellipse at center,
rgba(255,255,255,1) 0%,
rgba(255,255,255,1) 50%,
rgba(255,255,255,0) 80%);
为了解决这个限制,我修改了找到背景图片网址的行,如下所示:
var bgImg = style.backgroundImage.match(/url\(([^\)]+)\)/)[1].replace(/"/g, '');
这使用正则表达式来仅提取背景图像的URL部分。
我会将此作为评论添加到linked answer,但我是一个没有声望的菜鸟,因此被禁止这样做。具有足够代表的人可能希望将该行添加到实际答案中。