guns
guns

Reputation: 10815

Recursive image lazy-load failing in Internet Explorer (6-8)

Problem:

I am having trouble implementing a recursive image lazy load in all relevant versions of Internet Explorer. I am using jQuery 1.3.2, and the code that follows works wonderfully on Firefox, Safari, and Chrome.

While I would expect that IE6's javascript engine would choke, I am very surprised to find that it does not work at all on IE7, and only occasionally on IE8. That it works sometimes on IE8 is frustrating, because it seems to imply that if I work hard enough and set enough breakpoints in the Microsoft script debugger, I'll perhaps get it to work after some struggle.

I'm aware that I don't have to do this recursively, and I will reimplement it if I don't find a suitable solution, but the recursive approach is particularly suitable in this example because I would like the images to load one at time, prettily in a row. (And I expect a max depth of around 15)

I've come to StackOverflow with this question because I've run up against this a problem like this in the past and would like to know if anyone has any insights into what the problem may be:

Code:

Here is the lazy-load function:

jQuery.lazyLoadImages = function(imgSelector, recursive, fadeIn)
{
  var image = $(imgSelector);
  if (image.size()) {
    image.parents(SAH.imageContentSelector).addClass(SAH.loadingClass);
    // the img src attribute is stored in the alt attribute
    var imgSrc = image.attr('alt');
    image.attr('src', imgSrc).attr('alt','').load(function() {
      $(this)
      .removeClass(SAH.lazyLoadClass)
      .parents(SAH.imageContentSelector)
      .removeClass(SAH.loadingClass);
      if (fadeIn) $(this).fadeIn(SAH.lazyLoadDuration);
      if (recursive) {
        var nextPos = eval(parseInt(imgSelector.replace(/.*position-(\d+).*/,'$1')) + 1);
        var nextImage = imgSelector.replace(/position-(\d+)/,'position-' + nextPos);
        $.lazyLoadImages(nextImage, recursive, fadeIn);
      }
    });
    return true;
  } else {
    return false;
  }
}

The SAH.* variables are just variables stored in a global object, SAH. Here is the relevant section that calls $.lazyLoadImages():

// fade the first image in with the navBar
var firstGalleryImageSelector = 'img#img-position-1-' + galleryId + '.' + SAH.lazyLoadClass;
$.lazyLoadImages(firstGalleryImageSelector,false,true);
navBar.show('slide', { direction: 'right' }, function() {
  // load the rest after the navBar callback
  $.lazyLoadImages(firstGalleryImageSelector.replace(/position-1/,'position-2'), true, true);
});

The first call to $.lazyLoadImages() is non-recursive; the second one is recursive and fires after a navigation bar slides into the window.


Finally, here is the relevant html:

<div id='position-1-i4design' class='content image' style='width:400px'>
  <div class='image-gallery'>
    <a class='local-x' href='#position-1-i4design'>
      <img alt='/images/press/i4design/i4design-1.jpg' id='img-position-1-i4design' class='lazy-load hide'>
    </a>
    ...
  </div>
  ...
</div>

<div id='position-2-i4design' class='content image' style='width:389px'>
  <div class='image-gallery'>
    <a class='local-x' href='#position-2-i4design'>
      <img alt='/images/press/i4design/i4design-2.jpg' id='img-position-2-i4design' class='lazy-load hide'>
    </a>
    ...
  </div>
  ...
</div>

<div id='position-3-i4design' class='content image' style='width:398px'>
  <div class='image-gallery'>
    <a class='local-x' href='#position-3-i4design'>
      <img alt='/images/press/i4design/i4design-3.jpg' id='img-position-3-i4design' class='lazy-load hide'>
    </a>
    ...
  </div>
  ...
</div>

...

Upvotes: 4

Views: 4381

Answers (2)

ern
ern

Reputation: 1512

I have done something very similar with a recursive JavaScript function to load images, which works fine in IE.

The major differences that I can see are:

  • I used a normal JavaScript function, not a jQuery function.
  • I created each image with jQuery and added it to the relevant container.

I'm not sure if either of those points matters, but just looking at your code, I'm guessing that some more expensive functions would be referencing the image's parents twice, and also fading the image in.

Does it successfully run if those are commented out?

Upvotes: 1

ajm
ajm

Reputation: 20105

The IEs need onload Events defined for images before you attempt to set that Element's src. All other browsers will handle that just fine; the IEs will choke.

It's likely that your load function in the above will never run for that reason.

Give this a try:

   image.attr('alt','').load(function() {
      $(this)
      .removeClass(SAH.lazyLoadClass)
      .parents(SAH.imageContentSelector)
      .removeClass(SAH.loadingClass);
      if (fadeIn) $(this).fadeIn(SAH.lazyLoadDuration);
      if (recursive) {
        var nextPos = eval(parseInt(imgSelector.replace(/.*position-(\d+).*/,'$1')) + 1);
        var nextImage = imgSelector.replace(/position-(\d+)/,'position-' + nextPos);
        $.lazyLoadImages(nextImage, recursive, fadeIn);
      }
    }).attr('src', imgSrc);

Upvotes: 8

Related Questions