Question

I need to change background image size for several dinamic blocks:

<div class="preview" style="background:url(http://site/image1.jpg)"></div>
<div class="preview" style="background:url(http://site/image2.jpg)"></div>
<div class="preview" style="background:url(http://site/image3.jpg)"></div>

This is a way how I try to set background size:

$('div.preview').each(function(){
    var x = y = 98;

    ths = $(this);
    var img = new Image();
    img.src = $(this).css('background-image').slice(4, -1);

    img.onload = function(e){
         if (this.width > this.height)
         {
             var scale = 100 * 98 / this.width;

             if (scale < 100)
             {
                 ths.css('background-size', 'auto ' + (100 - scale + 2) + '%');
             }
         }
         else
         {
             var scale = 100 * 98 / this.height;

             if (scale < 100)
             {
                 ths.css('background-size', (100 - scale + 4) + '% auto');
             }
         }
    }
});

But in this case image-size changes only for image3.jpg. How to change others?

Was it helpful?

Solution

The problem is that ths is not a local variable.

So, for every element processed by .each, the same global property (window.this) is re-assigned. The last time it is assigned, it refers to "image3" - and thus all the asynchronous onload events, which occur later, will refer to "image3".

The quickest fix is to add var and change the code to:

var ths = $(this);

This makes ths a local variable, which will be distinct for each element processed by .each (as each element is processed in a new function scope), that is bound in the closure formed by the onload callbacks.

Here is a working fiddle (thanks, Ani!)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top