GG.
GG.

Reputation: 21834

jQuery .load on image fires once

Context

A user page with HR information.

I have a menu under the user picture which has an unfixed size.

I update the menu margin-top when the picture is loaded:

_setMenuMarginTop: function () {
    var that = this;

    $('#picture > img').load(function () {
        that.$el.css('margin-top', $(this).height() + 'px');
    });
}

When the current user is changing, I update the page (user info, user picture img) then I recall the method _setMenuMarginTop as the picture size isn't the same:

initialize: function () {
    this.listenTo(app.curUser, 'sync', this._updateView);
},

...

_updateView: function () {
    this._setMenuMarginTop();

    // Other stuffs...
},

But this time jQuery doesn't fire the .load method.

Questions

More info

The img update into an other view:

initialize: function () {
    this.listenTo(app.curUser, 'sync', this._updateCurUserInfo);
}

...

_updateCurUserInfo: function () {
    this.$el.find('#picture').html( this.templatePicture({ 'url' : getPictureUrl(app.curUser.get('picture')) }) );

    // Other stuffs...
}

Upvotes: 3

Views: 659

Answers (3)

suff trek
suff trek

Reputation: 39777

I believe assigned image src should be different each time for load to fire. Consider following demo: http://jsfiddle.net/j4tP8/1/

I am using basic image and button

<button id="one">One</button>
<img id="img" />

Which connected via

$('#one').click(function() {
    $('#img').attr('src','https://site/image.jpg')
})

$('#img').load(function() {
    alert('loaded');
})

When you click the button - image is assigned source. As it is load event will fire only once. But f you modify the code by adding random string to the source:

$('#one').click(function() {
    $('#img').attr('src','https://site/image.jpg?' + Math.random() )
})

load will fire every time.

Upvotes: 0

adeneo
adeneo

Reputation: 318182

How about triggering the onload handler again ?

_setMenuMarginTop: function () {
    var that = this;

    $('#picture > img').on('load', function () {
        that.$el.css('margin-top', $(this).height() + 'px');
    }).each(function() {
         if (this.complete) $(this).trigger('load');
    });
}

And note that's it's an event handler, calling the function again just applies another event handler.

Upvotes: 2

Damien Black
Damien Black

Reputation: 5647

This happens because the new image doesn't have the load function on it. Replacing the image breaks the event. You can use the jQuery on function to always fire the event on all images that are in the #picture div:

$('#picture').on('load', 'img', function() {
    that.$el.css('margin-top', $(this).height() + 'px');
})

That should do it. This would replace your $('#picture > img').load(function () { line

What this does is attach the event to the '#picture' div, but actually fire when an 'img' inside the #picture div is loaded.

This way, if the picture is removed, the event isn't removed as well.

Upvotes: 0

Related Questions