[removed] onload and onerror called together

2019-02-15 05:01发布

问题:

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";
  }

回答1:

You are calling the functions, not assigning!

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

needs to be

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


回答2:

The problem with your second example is that the image callbacks are fired when the image loads, after your other code has been evaluated. I'm really not sure what your code accomplishes, but try something like this.

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

  function doSomething(img, d) {
     img.src = "http://.../peopleimages/" + d.num + ".jpg";
     alert(d.src);
     return d.src;
  };