使用jQuery更改图像src属性在Chrome/Opera上并不总是生效

20

我有以下的代码,用于检索我网站上照片的一个小高清部分。这样做是为了让人们在决定是否购买之前,能够一窥原始图片的质量:

$('#magviewplus').attr('src', '/photos/original-snippet.php?id=<?php echo $nID?>&x='+left+'&y='+top).load(function() {
    window.clearInterval(maginterval);
    magtimer=3;
    maginterval=window.setInterval(magViewCountdown,1000);
    $('#clicktoenhance').html('Exiting in '+magtimer+'s...');
});

因某种原因,这是间歇性的。Fiddler 显示该代码片段始终已加载,但它只有在某些时候才会显示。即使不显示,load() 事件中的代码也能正常运行。

所以它认为自己已加载,Fiddler 显示它已加载,但大约50%的时间它实际上并没有在应该出现的地方显示。

这种情况在我家里的台式电脑上发生较少,在我外出时使用的笔记本电脑上发生得更多,因此我想知道它是否与资源有时加载比较慢有关...?

有任何想法吗?

编辑: 这实际上似乎限于 Chrome 和 Opera,Firefox / IE11 中运行良好。


magViewCountdown是做什么的? - mplungjan
@Codemonkey,你在Chrome和Firefox中不使用Adblock插件吗?也许它们不喜欢你的图像src中的“.php”。 - Kevin
@Codemonkey 如果我访问 '/photos/original-snippet.php?id=123 ..' 会发生什么? - Kevin
你能在 Fiddle 上重现你遇到的问题吗?通过尝试构建 Fiddle,你很可能会找出问题所在... - Denys Séguret
@Codemonkey 这个问题已经有答案了,但是并没有让我满意,所以出于好奇,你能否试着在你的代码中更改 $('#magviewplus').attr$('#magviewplus').unbind("load").attr 并告诉我是否有任何影响?谢谢。 - Drakes
显示剩余2条评论
6个回答

5

编辑以展示这并不起作用...

起初看来,一个实际的“解决方案”是移除并重新添加图片:

<div id="magviewholder"><img id="magviewplus" src="pixel.gif" alt=""></div>

像这样:

$('#magviewholder').children("img").remove()
$('#magviewholder').append('<img>');

$('#magviewholder>img').attr('onerror','imgError(this)').attr('id','magviewplus').attr('src', '/photos/original-snippet.php?id=<?php echo $nID?>&x='+left+'&y='+top).load(function() {
     window.clearInterval(maginterval);
     magtimer=3;
     maginterval=window.setInterval(magViewCountdown,1000);
     $('#clicktoenhance').html('Exiting in '+magtimer+'s...');
 });

一开始似乎在所有浏览器中都能正常工作,但现在似乎也出现了不稳定的情况...


你能提供导致图像显示的步骤吗?例如...“用户点击图像..用户进入页面X...页面加载...在页面加载时,图像src被替换...在某些其他函数x发生”...另外为什么要使用load?也许可以提供一下你正在做的演示? - Cayce K

4

看起来你的问题已经有详细记录,以下帖子可以证明:

  1. jquery callback on image load when changing the src

  2. Capturing load event for images dynamically changing their source

  3. jQuery callback on image load (even when the image is cached)

我建议你将新图片加载到内存中,当这张新图片的加载事件触发时,改变实际图片的src并执行其他必要操作。原始图片保持不变,除了加载事件外的任何其他事件(例如click)都应该保持不变:

$(new Image()).attr('src', '/photos/original-snippet.php?id=<?php echo $nID?>&x=' + left + '&y=' + top).load(function() {
    $('#magviewplus').attr('src', this.src);
    window.clearInterval(maginterval);
    magtimer = 3;
    maginterval = window.setInterval(magViewCountdown,1000);
    $('#clicktoenhance').html('Exiting in ' + magtimer + 's...');
});

DEMO


我仍然坚持认为,我的问题并不是关于加载事件本身的...... 但将src加载到内存中,然后通过load事件分配给图像似乎已经解决了问题。 我会在整个一天进行测试,看看是否始终修复,然后再接受答案。 - Codemonkey
完成测试后请告诉我您的发现。如果您找出了可能导致问题的原因,请随时分享;如果您能提供演示,那将是找到根本原因的重要一步。 - PeterKA
我不得不调整一些缓存以避免图像加载两次(这显然会减慢速度),但现在我已经做到了,一切似乎都很好。但是,我很抱歉没有时间或意愿将其分解为演示... :( - Codemonkey

1
你可以使用图像 onload 事件。

当图像加载完成时,该事件处理程序将在图像元素上调用。

代码

var url = '/photos/original-snippet.php?id=<?php echo $nID?>&x='+left+'&y='+top;

var img = new Image();

img.onload = function () { 
    //When load's sucessfully
    $('#magviewplus').prop('src', url); 

    window.clearInterval(maginterval);
    magtimer=3;
    maginterval=window.setInterval(magViewCountdown,1000);
    $('#clicktoenhance').html('Exiting in '+magtimer+'s...');
};

img.onerror = function () { 
    //When load's fails
}; 

img.src = url; //Set URL

2
在设置 .src 之前,您应该先定义 onload - 不过这与 jQuery.load 相同吗? - mplungjan
很不幸,这似乎展示了完全相同的问题。 - Codemonkey
@Codemonkey,你在其他地方使用相同的URL吗? - Satpal

0
使用.load()方法加载图片:
$('#magviewplus').load('/photos/original-snippet.php?id=<?php echo $nID?>&x='+left+'&y='+top, function() {
    window.clearInterval(maginterval);
    magtimer=3;
    maginterval=window.setInterval(magViewCountdown,1000);
    $('#clicktoenhance').html('Exiting in '+magtimer+'s...');
});

我已经尝试了,看起来完全没有作用。查看jquery文档,它似乎是用于HTML片段的,因此在这种情况下不会起作用。 - Codemonkey

-1
尝试将“name”属性放在具有与“id”属性相同值的标签中。
<id="magviewplus" name="magviewplus".../>

这样,即使在Chrome中,jQuery也可以检测属性并正确更改,对于较旧版本的jQuery我不确定这是否有效,希望这有所帮助


-1
问题可能与客户端资源缓存策略有关,这取决于浏览器及其设置。如果是这样,您可以通过将随机数作为参数附加到地址字符串来强制重新加载图像。从服务器的角度来看,此参数毫无意义,但对于浏览器来说,它是一个全新的资源,即使实际上它是相同的。下面的示例说明了这种方法:

$('#loadbtn').click(function(){
  $('#msg').html("loading...");
  $('#myimg').attr("src", "http://cache1.asset-cache.net/xt/165920320.jpg?v=1&g=fs1%7C0%7CISI%7C20%7C320&s=1" + 
    "&rnd=" + Math.random());
});

$('#myimg').load(function(){
  $('#msg').html("loaded");
});
#loadbtn {
  margin: 16px;
}
#msg {
  margin: 16px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img id='myimg' src='http://cache1.asset-cache.net/xt/165920320.jpg?v=1&g=fs1%7C0%7CISI%7C20%7C320&s=1' />
<div>
  <input type=button id='loadbtn' value='reload' />
</div>
<div id='msg'>loading...</div>


我在问题中明确声明,我可以在 Fiddler 中看到资源正在被加载。所以这不是一个缓存问题。而且大多数请求已经是新的/独特的了。 - Codemonkey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接