也许是一个愚蠢的问题,但无论如何都要进行。
示例:假设我有一个非循环动画GIF,我有两个img元素。
<img src="" id="slot1" />
<img src="" id="slot2" />
所以我使用一些小的javascript来改变slot1的来源。
function changE(x)
{var image=document.getElementById (x);
image.src="animated.gif";
}
someButtonGotClicked=changE('slot1');
工作正常。 Gif从头到尾播放,但如果我然后将slot2的src更改为相同的gif:
changE('slot2');
slot1重置它的gif回到开始与slot2同步,启动它的gif。
现在我知道我可以复制gif并使用2个单独的文件,我知道精灵表,但我很好奇如果我可以使用gif的一个副本并且多次使用它在没有重新启动所有gif实例的页面上,每次另一个img元素收到与它的src相同的文件?
希望这并不令人困惑。感谢。
答案 0 :(得分:8)
将图像加载到内存中后,使用相同URL请求该图像的所有其他对象将从浏览器缓存中获取对该图像的引用。这可以避免多次加载相同的图像。在gif的情况下,要跟踪的元数据之一是当前帧,它不存储在<img>
dom元素中,而是存储在用于存储该元素的结构中的浏览器级别。 GIF。
加载时,重置该帧索引。因此,当浏览器正在处理gif循环时,第二个图像加载将当前帧索引设置为开头,因此两个图像同步。
这是一个浏览器实现,似乎大多数浏览器都遵循此实现。这样做的一个优点是,如果你在一个页面中有数千个小GIF(来自同一个URL),那么浏览器在渲染它们时计算量会少很多,因为它只会改变一个帧索引,而不是数千个。
编辑: 要修复代码,您必须在图像末尾添加随机内容。
function changE(x)
{var image=document.getElementById (x);
image.src="animated.gif?" + Math.random();
}
因此浏览器认为这是一个不同的图像(即不同的URL)。
答案 1 :(得分:0)
尝试使用类似的解决方案:
<img src="" id="slot1" class="animate" />
<img src="" id="slot2" class="animate" />
(function(doc, w) {
var changE, getElementsByClassName;
changE = function(img) {
img.src = "animated.gif";
};
getElementsByClassName = function(node, classname) {
if (node.getElementsByClassName) { // use native implementation if available
return node.getElementsByClassName(classname);
} else {
return (function getElementsByClass(searchClass, node) {
if (node == null)
node = doc;
var classElements = [],
els = node.getElementsByTagName("*"),
elsLen = els.length,
pattern = new RegExp("(^|\\s)" + searchClass + "(\\s|$)"), i, j;
for (i = 0, j = 0; i < elsLen; i++) {
if (pattern.test(els[i].className)) {
classElements[j] = els[i];
j++;
}
}
return classElements;
})(classname, node);
}
};
w.onload = function() {
var imgs, i = 0, l;
imgs = getElementsByClassName(doc, 'animate');
l = imgs.length;
for (i; i < l; i++) {
imgs[i].onclick = function(e) { changE(this); };
}
};
})(document, window);
这将为每个具有班级名称animate
的图片设置点击事件,点击事件只会影响点击的特定图片。