javascript: onload and onerror called together

wceo picture wceo · Sep 20, 2012 · Viewed 18k times · Source

I'm new to JavaScript and therefore confused for the variable scope... I'm trying to load an image, and replace it with another URL when it doesn't exist. I have to do it in pure JavaScript.

Here I got 2 versions extremely alike, but they perform differently. The only thing in common is: they don't work. The 3rd version requires a refresh and doesn't work under IE. d is the object with number attribute, which has no problem.

Here is what they have in common

.attr("xlink:href", function (d) {
  var img = new Image();

Here the Version 1: Both onload and onerror are called. However d receives the src, unfortunately it's always the generic.jpg.

  function onLoadHandler() {
     d.src = "http://.../peopleimages/" + d.num + ".jpg";
     alert(d.name + " onload called");
  }
  function onErrorHandler() {
     d.src = "http://.../images/generic.jpg";
     alert(d.name + " onerror called");
  }
  img.onload = onLoadHandler();
  img.onerror = onErrorHandler();
  img.src = "http://.../peopleimages/" + d.num + ".jpg";
  return d.src;
  }

Here the Version 2: Depending on the existance of the image, either onload or onerror is called. But the value of d.src is undefined when alert.

  img.onload = function () {
     alert(d.name + " : loaded");
     d.src = "http://.../peopleimages/" + d.num + ".jpg";
  }
  img.onerror = function () {
     alert(d.name + " : failed");
     d.src = "http://.../images/generic.jpg";
  }

  img.src = "http://.../peopleimages/" + d.num + ".jpg";
  alert(d.src);//undefined
  return d.src;
  }

Here the Version 3: it works but not the first time. I have to do refresh to get the images correctly. Perhaps it returns before the image is loaded completely.

  img.src = "http://.../peopleimages/" + d.num + ".jpg";
  return img.complete ? "http://.../peopleimages/" + d.num + ".jpg" : "http://.../images/generic.jpg";
  }

Answer

epascarello picture epascarello · Sep 20, 2012

You are calling the functions, not assigning!

img.onload = onLoadHandler();
img.onerror = onErrorHandler();

needs to be

img.onload = onLoadHandler;
img.onerror = onErrorHandler;