0

I've read jquery: how to listen to the image loaded event of one container div?

My case is similar: I have a <body contentEditable="true"/> tag that is edited with a visual editor. The innerHTML of this body is modified by the editor and events are fired.

The problem is that I have to handle a resize logic. The current resize logic in the library is:

    this.$body.on('keyup keydown paste change focus', function() {
        return _this.adjustHeight();
    });

This works pretty fine except the change event is not fired on drag&dropping images, but fortunatly a focus event is triggered. But when the event is fired, the image is not loaded yet so it doesn't resize to the good size.

What is the best way to listen to image loadings for images that are added to the DOM lately using Js code? I tried using $(window).load(fn) but didn't catch anything.

Community
  • 1
  • 1
Sebastien Lorber
  • 89,644
  • 67
  • 288
  • 419
  • Sadly, the _load_ event on a _HTMLImageElement_ does not bubble. – Paul S. Feb 26 '14 at 11:58
  • Well, couldn't you add a `load` listener on the dropped images? Since you know that `focus` is triggered, you can check whether one of the images in `body` is new (place some flag in a `data-` attribute) and add a `load` listener. – Zeta Feb 26 '14 at 12:01
  • @Zeta It might be better to edit the drop code such that if you create a ``, you `addEventListener` for _load_ to fire a `new Event` (called something like `"image_loaded"`) which **does** bubble. – Paul S. Feb 26 '14 at 12:01

1 Answers1

2

You could bind the adjustHeight function to the load event of image elements as they are added, like so;

this.$body.on('keyup keydown paste change focus', function() {
    $(this).find('img').off('load', _this.adjustHeight).on('load', _this.adjustHeight);
    return _this.adjustHeight();
});
  • $(this) is the same as this.$body (but allows you to extract the function outside it's current holder).
  • .find('img') gets all image elements within $(this) (so within the editable area)
  • .off('load', _this.adjustHeight) removes the event handler from the image element, without this you could end up binding the function several times which would also cause it to be called just as many times which could become a performance issue easily
  • .on('load', _this.adjustHeight) adds the event handler to the image element, so this gets called when the image is loaded

What comes to mind is that you might need to throttle the adjustHeight function to not be called too often to prevent it from freezing up your browser when a user drags and drops a lot of images at once (unless it isn't as expensive a function as I imagine it could be). But if this does turn out to be an issue you would probably also have to do that with other solutions.

Martijn Hols
  • 1,470
  • 1
  • 10
  • 21
  • Don't just paste code as answer, give a little explanation – Fabio Antunes Feb 26 '14 at 13:06
  • 1
    Apologies, I didn't have too much time but saw a potential solution that I wanted to share before forgetting about the entire question. I updated the answer with more information. – Martijn Hols Feb 26 '14 at 13:33
  • Thanks. Actually I detected another problem. The focus event is triggered before the img node is appended to the dom :( so it doesn't work well (I'm trying to use this code to work around this behavior): http://stackoverflow.com/a/14570614/82609). By the way I think your code may not handle well images that are already loaded in cache, because the load event may be triggered before the event listener is setup – Sebastien Lorber Feb 26 '14 at 13:37