使用 jQuery 更改图像 src 属性并不总是适用于 Chrome/Opera

Changing an image src attribute with jQuery not always applied in Chrome/Opera

我有以下代码用于在我的网站上检索照片的一小部分高分辨率。目的是让人们在决定是否购买之前先看看原作的质量:

$('#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

中运行良好

使用.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...');
});

您可以使用图像 onload 事件。

This event handler will be called on the image element when the image has finished loading.

代码

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

编辑显示这不起作用...

一开始似乎务实的 "solution" 是删除并重新添加图像:

<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...');
 });

起初这似乎在所有浏览器中都有效,但现在似乎断断续续...

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

$('#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>

您的问题似乎已得到充分记录,从以下帖子中可以明显看出:

  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 并执行任何其他需要完成的操作。原始图像保持不变,附加到它的任何其他事件(加载除外)应保持不变:

$(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

尝试将 de "name" 属性 放入具有与 "id" 属性 相同值的标签中。

<id="magviewplus" name="magviewplus".../>

以这种方式 jquery 即使在 chrome 中也检测到属性并正确更改,在 jquery 的较旧版本中我忽略了这是否有效,希望这有助于