20

I have the following bit of code which is used to retrieve a small high-res portion of a photo on my website. The idea being to let people have a glimpse at the original's quality before deciding whether to purchase or not:

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

For some reason, it's intermittent. Fiddler shows that the snippet is always loaded, but it's only displayed sometimes. Even when it doesn't display though, the code in the load() event runs just fine.

So it thinks it's loaded, Fiddler shows that it's loaded, but about 50% of the time it doesn't actually display where it should.

It tends to happen less on my desktop at home, and more on my laptop when I'm out and about, so I wonder if it's somehow related to the resource being a bit slow loading at times...?

Any ideas?

edit: this actually appears to limited to Chrome & Opera, it works fine in Firefox/IE11

Glenn Ferrie
  • 10,290
  • 3
  • 42
  • 73
Codemonkey
  • 4,455
  • 5
  • 44
  • 76
  • what does magViewCountdown do? – mplungjan Apr 08 '15 at 08:41
  • Nothing relevant - just updates the clicktoenhance text - shows a countdown, and then hides the box when the countdown has finished. – Codemonkey Apr 08 '15 at 10:15
  • @Codemonkey Don't you use Adblock plugins in your Chrome and Firefox? Maybe they don't like ".php" in your image src – Kevin May 05 '15 at 07:59
  • @Codemonkey What will happen if I will go to '/photos/original-snippet.php?id=123 ..' ? – Kevin May 05 '15 at 08:05
  • No adblock etc. And if you went to the URL you'd see the image, just as if you browsed to my-photo.jpg. It's served up with the correct mime type, if that's what you're wondering. – Codemonkey May 05 '15 at 11:13
  • Can you reproduce this problem you have in a fiddle ? It's probably you'll identify the problem by trying to build the fiddle... – Denys Séguret May 05 '15 at 14:26
  • @Codemonkey This question is answered, but not to _my_ satisfaction, so out of curiosity, would you kindly try this in your code and tell me if it has any effect? Simply change `$('#magviewplus').attr` to `$('#magviewplus').unbind("load").attr`. Thank you. – Drakes May 06 '15 at 13:37

6 Answers6

5

edited to show that this doesn't work...

It seemed at first that a pragmatic "solution" was to remove and re-add the image:

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

Like so:

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

This appeared to work in all browsers at first, but seems to be just as intermittent now...

Codemonkey
  • 4,455
  • 5
  • 44
  • 76
  • can you provide the steps that lead to the display of the image? for example... `User clicks on image.. user taken to page X... page loads... on page load the image src is replaced... on some other function x happens`... also why use load? maybe provide a demo of what you're doing? – Cayce K May 05 '15 at 12:47
4

Looks like your issue is well-documented as is evident from the following posts:

  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)

I would suggest you load a new image into memory, then when this new image's load event fires, change the src of the actual image and do whatever else needs to be done. The original image remains intact and any other events (other than load) attached to it should remain intact:

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

Community
  • 1
  • 1
PeterKA
  • 24,158
  • 5
  • 26
  • 48
  • I still maintain that my question isn't about the load event, per se.... But loading the src into memory and then assigning (via the load event...) to the image does appear to have fixed things, I think. I'll test throughout the day and see if it's consistently fixed before accepting. – Codemonkey May 06 '15 at 08:38
  • Let me know your findings once you completer your testing. And, if you figure out what you think may be causing the issue feel free to share; if you can provide a demo, that would be a giant step toward finding the root cause. – PeterKA May 06 '15 at 11:40
  • I had to adjust some caching to avoid the image loading twice (which obviously slowed it down) using your code, but now that I've done that everything seems pretty good. I don't have the time or inclination to hack it apart into a demo I'm afraid... :( – Codemonkey May 06 '15 at 12:44
1

You can use Image onload event.

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

Code

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
Satpal
  • 132,252
  • 13
  • 159
  • 168
0

Use .load() to load the image:

$('#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...');
});
Brijesh Bhatt
  • 3,810
  • 3
  • 18
  • 34
  • I tried it, and it doesn't appear to work at all, and looking at the jquery docs that seems to be for HTML snippets, so it wouldn't work in this scenario. – Codemonkey Apr 08 '15 at 10:06
-1

The problem may be related to the client resource caching policy which depends on the browser and its settings. If so, you can force the image reload by appending a random number as parameter to the address string. From the server point of view this parameter is meaningless, but for the browser sees it as a completely new resource, even actually it's the same. Below sample illustrates this method:

$('#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>
Alexander Dayan
  • 2,846
  • 1
  • 17
  • 30
  • I clearly stated in the question that I can see the resource being loaded in Fiddler. Ergo it's not a caching problem. And most of the requests are new/unique already. – Codemonkey May 06 '15 at 08:10
-1

Try to put de "name" property in the tag with the same value like the "id" property.

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

in this way jquery even in chrome detects the atribute and change correctly, in the olders versión of jquery i ignore if this works, hope this help