mikedidthis
mikedidthis

Reputation: 4897

jQuery collections, function and organisation

I have the following code which takes a single image and applies a specific width to it:

function Foo ( img ) {
    this.image = img;
}
Foo.prototype._getWidth = function( ) {
    return this.image.data('largest') + 'px';
};
Foo.prototype.applyWidth = function(  ) {
    this.image.css( 'width', this._getWidth() );
};

var img = Foo( $('img') );

img.applyWidth();

However I am struggling to get my head around handling a jQuery collection of images, such as $('img') without a for loop or $.each()inside each of the functions (I have more than these two functions shown above).

So far the best I have come up with is:

var temp = [];

function Create ( imgs ) {
    $.each( imgs, function( i ){
        temp[ i ] = new Foo ( $( this ) );
    });
    return temp;
}

Create( $('img') );

$.each( temp, function() {
    $(this).applyWidth();
}):

This works fine, but it doesn't feel organised, feels sloppy.

Finally, I would like some guidance on the following.

  1. I ideally want this under the namespace Theme. I would like this method under Theme.Images using the module pattern. Is this possible?

  2. If under the namespace Theme.Images would it be possible to make a call such as Theme.Images.applyWidth() that would call applyWidth() on all the images in temp, bearing in mind each img would have a unique value for _getWidth(). At the moment I believe I would need to loop Theme.Images.temp and call applyWidth() inside the loop.

I am really starting to appreciate the point of inheritance in javascript, and would like to continue with it.

Upvotes: 6

Views: 148

Answers (2)

Naftali
Naftali

Reputation: 146302

var Theme = (function(){

    function Theme(images) {
        var _this = this;
        this.images = [];
        images.each(function(){
           _this.images.push(new Image(this))
        });
    }

    var Image = (function(){

        function Image(imageDOM) {
            this.image = $(imageDOM);
        }
        Image.prototype._getWidth = function( ) {
            return this.image.data('largest') + 'px';
        };
        Image.prototype.applyWidth = function(  ) {
            this.image.css( 'width', this._getWidth() );
        };

        return Image;

    })();

    Theme.prototype.applyWidth = function(){
        this.images.forEach(function(el){
            el.applyWidth();
        });
    }


    return Theme;

})();

So then you can do:

var MyTheme = new Theme($(some_selector));
MyTheme.applyWidth();

Upvotes: 1

Florian Margaine
Florian Margaine

Reputation: 60717

Sounds like to me you're looking for a "Collection" class.

function Images() {
    var that = this;
    that.foos = [];
    $('img').each(function() {
        that.foos.push(new Foo(this));
    });
}

Images.prototype.applyWidth = function() {
    $.each(this.foos, function() {
        this.applyWidth();
    });
};

Upvotes: 1

Related Questions