2

I'm building my own photo gallery in javascript, partially for the experience, partially for a project. Right now, I'm getting stuck with some issues around objects.

When an Image object is created, it is pushed to an array in the Gallery object. Around the comment // constrain to width (line 55 in the gist), I'm trying to get the width and height properties from the object. If I console.log the variable img, I can see the properties and functions of the object. However, if I console.log(img.height);, I get undefined. What am I doing wrong?

The entire file is below. It's also here in a gist for easier reading.

var Image = function(img, gallery){
    // init with an image in jquery form
    this.src = img.attr('src');

    this.setDimensions = function(){
        var temp_height, temp_width;
        $this = this;
        $this.image = $('<img />').attr('src', this.src).load(function(){
            $this.height = this.height;
            $this.width = this.width;
        });
    };

    // init functions
    this.setDimensions();
    gallery.images.push(this);


}; // Image

var Gallery = function(){
    this.width = $(window).width();
    this.height = $(window).height();
    this.images = [];

    this.createElements = function(){
        $('body').append('<div id="the_gallery"></div>');
        $('#the_gallery').css({width: this.width, height: this.height});
    };

    this.open = function(){
        this.createElements();

        var img = this.images[0];

        // see if the image is bigger than the window
        if( this.width >= img.width && this.height >= img.height) {
            console.log('image < window');
            // just show the image, centered
        }

        else {
            console.log('image > window');
            var temp_width, temp_height;
            // constrain to height
            if( img.width < img.height ) {
                console.log('image width < image height');
                temp_height = this.height;
                temp_width = (temp_height/img.height) * img.width;

                img.css({height:temp_height, width:temp_width});

            }

            // constrain to width
            else {
                console.log('image width > image height');
                temp_width = this.width;
                temp_height = (temp_width/img.width) * img.height;
                img.image.css({height:temp_height, width:temp_width});
            }

        }

        img.image.appendTo($('#the_gallery'));

    }; // open

    this.close = function(){
        $('#the_gallery').remove();
    }; // close
}; // Gallery

$(document).ready(function(){
    $('#gallery img').click(function(){
        launchGallery($(this));
    }); // click

    var gallery = new Gallery(),
        test = new Image($('#gallery img:first'), gallery);

    gallery.open();
}); // doc ready
hookedonwinter
  • 11,741
  • 17
  • 55
  • 73
  • So that I might ask better questions, why the down vote and the vote to close? – hookedonwinter May 22 '12 at 03:14
  • "If I console.log the variable img, I can see the properties and functions of the object. However, if I console.log(img.height);" –  May 22 '12 at 03:24
  • @pst it's a timing/async issue, that is actually happening. I was puzzled too. – Ricardo Tomasi May 22 '12 at 03:30
  • @pst Appears it's the cacheing issue - FF doesn't show the properties in the log. Time to fix the async issue. – hookedonwinter May 22 '12 at 03:31
  • 3
    This probably isn't related to your immediate problem, but **you should rename your object**. `Image` is a built-in host object (DOM 0); overwriting it (which you are doing) could cause other scripts to break. – josh3736 May 22 '12 at 03:32
  • @josh3736 thought that might cause a problem. I'll update that for sure. Thanks! – hookedonwinter May 22 '12 at 03:33
  • 1
    @hookedonwinter Again, that statement holds true. Address that first for a reliably diagnostic base *and* will allow writing a **useful** title. I didn't down-vote, but I will not up-vote either. –  May 22 '12 at 03:33
  • Why use function expressions when function declarations are available? – RobG May 22 '12 at 03:41
  • Updated the gist with working code that allows for the async issues. Just starting development, so things are likely to change. Thanks everyone for your help! https://gist.github.com/2766269 – hookedonwinter May 22 '12 at 03:43
  • @RobG Most likely because I don't know the difference. Googled, and am now reading http://stackoverflow.com/questions/1013385/what-is-the-difference-between-a-function-expression-vs-declaration-in-javascrip to learn. – hookedonwinter May 22 '12 at 03:44
  • Cool, make sure you read [kangax's linked article](http://kangax.github.com/nfe/). Unusual that you hadn't come across declarations before, I think they are preferable to expressions where either will do the job. But of course expressions are very useful when used appropriately. – RobG May 22 '12 at 23:36
  • @RobG Well, i've come across them, just didn't really understand the difference and why one is better than the either. Either way, thank you for your comments. – hookedonwinter May 23 '12 at 17:42

2 Answers2

2

I voted for closing, but here is some help:

When you call new Image, you reload it and set width and height when the load event fires. That is after the rest of the code runs - when you get to that point line 55, the image might not be loaded yet.

A simple solution would be to just grab the width/height directly from img.width() and always run the plugin on window.onload. If you want to support dynamically loaded images you'll have to brush up on that logic, and wait until everything is loaded before building the gallery.

Also, avoid leaking globals, you're missing var in $this = this (line 7).

Ricardo Tomasi
  • 31,690
  • 2
  • 52
  • 65
  • Ah, didn't consider the timing issue. The console suggests the problem is elsewhere (https://skitch.com/hookedonwinter/85ih1/index.html), but, I'll definitely update that. I'm reloading it as the image is displayed as a thumbnail originally - via css not a different image - so the `.width()` was only showing 100px. – hookedonwinter May 22 '12 at 03:27
  • Spot check in FF shows it's definitely a timing issue. Thanks! – hookedonwinter May 22 '12 at 03:32
  • @hookedonwinter here's a quick rewrite with this issue in mind: http://jsbin.com/ibudok/2/ – Ricardo Tomasi May 22 '12 at 04:05
-1

I'm not sure about this: but its worth a try. Instead of "$('#the_gallery').css({width: this.width, height: this.height});"

Maybe try this:

"$('#the_gallery').css('width', this.width +'px').css('height', this.height +'px');"

AlvinfromDiaspar
  • 5,868
  • 13
  • 63
  • 120