2012-05-24 178 views
14

标题不言而喻,但我会提供有关此问题的分步视图。希望我不是第一个注意到Webkit/Chrome上的这个(显然)错误的人。使用显示重置GIF动画的正确方法:在Chrome上不显示任何内容

我想重置一个GIF动画。到目前为止,我所见过的所有例子不是简单地将图像的src设置为自身,就是将其设置为空字符串,然后再将其设置为原始的src

看看这个JSFiddle仅供参考。 GIF在IE,Firefox和Chrome上完全正常。

我的问题是当图像有display:noneGoogle Chrome只有

选中此JSFiddle。在显示在页面中之前,GIF在IE和Firefox上重置得很好,但Chrome只是拒绝重置它的动画!

我试过到目前为止:

  • 设置src到了自己在小提琴,不会在Chrome中工作。
  • src设置为空字符串并将其恢复为默认值也不起作用。
  • 在图像周围放置一个包装,通过.html('')清空容器并将图像放回其中,也不起作用。
  • 在设置src之前,通过.show().fadeIn()更改图像的display也不起作用。

只有的解决方法,我发现到目前为止是保持图像使用其默认display和操纵它通过.animate()荷兰国际集团和荷兰国际集团.css()的透明度,高度和能见度在必要时模拟display:none行为。

这个问题的主要原因(上下文)是我想重置一个ajax加载器GIF,然后将它淡入页面中。

所以我的问题是,有没有适当的方法来重置GIF图像的动画(这可以避免Chrome的display:none“bug”)还是它实际上是一个错误?

(PS。你可以改变在小提琴的GIF更适合自己的/更长的GIF动画进行测试)

+0

我制定了一个完整的解决方案。看到这里:http://stackoverflow.com/a/31093916/1520422 –

回答

24

与风格的变化不同于其他浏览器Chrome的交易。

在Chrome中,当您调用.show()时没有参数时,该元素实际上并没有立即显示在您调用它的位置。相反,Chrome 队列执行新风格的应用评估当前的JavaScript块;而其他浏览器会立即应用新的样式更改。然而,.attr()没有排队。因此,如果根据Chrome浏览器仍然无法看到该元素,则您正在有效地尝试设置src,并且当原始src和新src相同时,Chrome将不会执行任何操作。

相反,您需要做的是确保jQuery在设置了display:block之后设置了src。您可以利用setTimeout达到这样的效果:

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(); 
     } 
    ); 
}); 

这确保了srcdisplay:block已应用于元素后置

这部作品的原因是因为setTimeout的排队功能,用于执行(但长是),因此函数不再被认为是JavaScript的当前“块”的一部分,它提供Chrome浏览器首先渲染并应用display:block,从而使该元素在其src属性设置之前可见。

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

感谢Freenode的IRC的#jquery shoky提供一个简单的答案。


或者,您可以强制重绘以刷新批处理样式更改。这是可以做到,例如,通过访问该元素的offsetHeight属性:

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

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

+0

比从未更好的迟到,谢谢!我了解浏览器如何批量修改样式,但从未考虑它将应用于此用例。我现在会试验一下。 +1为有用的信息 –

+0

我已经编辑了您的答案,以添加我将在真实场景中使用的替代方案,以便我可以接受您的答案而不是提交自己的答案。谢谢。 –

+0

我该如何使用它来重置一个设置为css背景图片而不是SRC的gif?例如:http://bit.ly/1XKm8JC - 图像在第一次播放时工作正常,但在动画结束后,它回到开始季节问候gif不重新开始。我使用Edge Animate – KevinOrin

24

最可靠的方法来“复位”一个GIF是通过附加一个随机查询字符串。但是这意味着每次都会重新下载GIF,因此请确保它是一个小文件。

// reset a gif: 
img.src = img.src.replace(/\?.*$/,"")+"?x="+Math.random(); 
+2

+1,因为它实际上“修复”在铬中的问题,即使在显示它之前请求一个新的图像下载是违背我最初的概念已经拥有它缓存在页面中。我会继续打开这个问题来检查是否没有其他可能的解决方案,因为现在我会保留我的虚拟“display:none”行为。 –

+0

这段代码去哪里?我很乐意看到一个工作版本与jsFiddle – egr103

+1

感谢您的伟大解决方案尼特。这是我的'background-image'版本(它确实需要jQuery):'img。css('background-image',img.css('background-image')。replace(“.gif”,“.gif”+“?x =”+ Math.random()));' – Stan

4

solution预加载的GIF,并采取出来的DOM,然后再在src(从而避免再次下载)

我只是测试它使用jQuery来删除该属性和它工作正常。

例子:

<html> 
<head> 

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js" type="text/javascript"></script> 

<script> 

$(function() { 

    $('.reset').click(resetGif); 

    function resetGif() 
    { 
     $('.img1').removeAttr('src', ''); 
    } 
}); 

</script> 

</head> 

<body> 
    <img class="img1" src="1.gif" /> 
    <a href="#" class="reset">reset gif</a> 
</body> 
</html> 
1

这里是我的背景图像黑客:

$(document).on('mouseenter', '.logo', function() { 
    window.logo = (window.logocount || 0) + 1; 
    var img = new Image(); 
    var url = "/img/mylogimagename.gif?v=" + window.logocount; 
var that = this; 
    $(img).load(function(){ 

    $(that).css('background-image','url(' + url + ')'); 
    }); 
    img.src = url; 
}); 
+0

嗨,你能提供一些细节,了解需要改变哪些变量来使用它。我知道var url,但除此之外呢? – KevinOrin

2

这似乎为我工作Chrome,它每次在我淡入图像之前运行,并清除然后重新填充src,我的动画现在每次都从头开始。

var imgsrc = $('#my_image').attr('src'); 
$('#my_image').attr('src', ''); 
$('#my_image').attr('src', imgsrc); 
+0

最好的解决方案! –

+0

简单而有效 - 非常感谢 – alib0ng0

0

我在搜索其他许多人后发现了这个线程。戴维贝尔的文章让我知道了我需要的解决方案。

我想我会发布我的经验,它可以为任何人试图完成我以后的事情有用。这是一个HTML5/JavaScript/jQuery网络应用程序,它将通过PhoneGap作为iPhone应用程序。在Chrome中进行测试。

目标:

  1. 当用户敲击/点击按钮A,GIF动画出现和戏剧。
  2. 当用户点击/点击按钮B时,gif消失。
  3. 当用户再次点击/点击按钮A后,点击/点击按钮 B后,动画gif应该重新出现并从头开始播放。

的问题:A键的

  • 在点击/点击,我被追加GIF到现有股利。它会玩的很好。
  • 然后,点击/单击按钮B时,我隐藏了容器div,然后将gif的img src设置为空字符串('')。再次,没有问题(也就是说,问题还不明显)
  • 然后,点击/单击按钮A后,点击/单击按钮B后,我正重新添加到gif的路径作为src。

    - 这没有奏效。 gif会在后续点击/点击按钮A时显示...但是,我点击/点击的按钮A越多,gif加载和重新开始的次数就越多。也就是说,如果我来回走动,点击/单击按钮A然后按钮B 3次,gif会出现,然后开始/停止/启动3次...并且我的整个应用程序开始突然出现。我猜这个gif被多次加载,尽管当点击按钮B时,我已经将src设置为空字符串。

解决方案:

看着大卫·贝尔的文章后,我来到了我的答案。

  1. 我定义了一个全局变量(让我们称之为myVar),它将容器div和图像(包含源路径)保存在其中。
  2. 在按钮A的tap/click功能上,我将该容器div附加到dom中的现有父div上。
  3. 在这个函数中,我创建了一个新的变量来保存gif的src路径。

就像大卫的建议,我这样做(加追加):

$('#mainParent').append(myVar); 
var imgsrc = $('#my_image').attr('src'); 
$('#my_image').attr('src', ''); 
$('#my_image').attr('src', imgsrc); 

然后,在按钮B的功能,我在src设置为空字符串,然后取出包含DIV gif:

$('#my_image').attr('src', ''); 
$('#mainParent').find('#my_image').remove(); 

现在,我可以点击/点击按钮A,然后按钮B,然后按钮A等,整天。 GIF在点击/点击按钮A时加载和播放,然后隐藏点击/点击按钮B,然后在每次没有问题的情况下从按钮A的后续点击开始加载和播放。

2

只是因为我每时每刻都需要这个东西,我认为我使用的纯JS功能可能对别人有帮助。这是一个纯JS的重新启动GIF动画的方式,无需重新加载。您可以通过链接和/或文档加载事件调用此功能。

<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()调用。

--Nico

+0

此功能非常完美。 我必须改变以使其同样适用于Chrome: 'img.src =“#”;' 如果第一个src完全为空,则重新启动。 – vinni

0

我为这个问题找出了一个完整的解决方案。它可以在这里找到:https://stackoverflow.com/a/31093916/1520422

我的解决方案重新启动动画,而无需从网络重新加载图像数据。

它还强制重新绘制图像以修复发生的某些绘画假象(在chrome中)。

1

我有一个动画无循环图像的按钮。我只是用一些jquery重新加载图像,这似乎是为我工作。

var asdf = $(".settings-button img").attr("src"); 
$(".settings-button img").attr("src", "").attr("src", asdf); 
0

我遇到过所有上述解决方案的问题。最后什么工作是用透明的gif 1px的临时替换源:

var transparent1PxGif = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'; 
var reloadGif = function(img) { 
    var src = img.src; 
    img.src = transparent1PxGif; 
    img.offsetHeight; // triggers browser redraw 
    img.src = src; 
}; 
0

它已经好几年了,我已经决定重新审视这个,因为我们在我们的处置有一些新的选择。

my previous answer相关的问题是,它强制每次重新下载GIF时都要重新启动它。虽然这对小文件来说很好,但如果可能的话,这仍然是最好的避免的开销。

考虑到这一点,我有一个新的解决方案,它使用AJAX下载GIF一次,然后将其转换为数据URL(通过FileReader),并将其用作附带随机查询字符串的源。

这样,浏览器只会下载一次图像,甚至可以正确缓存它,并且“重置”从该预先下载的资源中提取。

唯一的问题是,在使用它之前,您必须确保它已正确加载。

演示:http://adamhaskell.net/misc/numbers/numbers.html

相关代码:

var url = "something.gif"; // fallback until the FileReader is done 
function setup() { 
    var xhr = new XMLHttpRequest(); 
    xhr.open("GET",url,true); 
    xhr.responseType = "blob"; 
    xhr.onreadystatechange = function() { 
     if(this.readyState == 4) { 
      var fr = new FileReader(); 
      fr.onload = function() { 
       url = this.result; // overwrite URL with the data one 
      }; 
      fr.readAsDataURL(this.response); 
     } 
    }; 
    xhr.send(); 
} 
function getGIF() { 
    return url+"?x="+Math.random(); 
}