Jacob J
Jacob J

Reputation: 301

How to pass jquery selections into a function?

I tried searching, but couldn't quite find what I was looking for. Hopefully this is super simple for someone.

This is the code i'm starting with that i'd like to turn into a function. Obviously there is a way to do this so I don't have to repeat.

var fullWidth = $('.full-img').width();
var paddBottom = fullWidth * .75;
$('.full-img').css('padding-bottom', paddBottom);

var thumbWidth = $('.img-box').width();
var thumbBottom = thumbWidth * .75;
$('.img-box').css('padding-bottom', thumbBottom);

Here's what I tried

function aspectRatioFix(main, thumb) {
    var fullWidth = main.width();
    var paddBottom = fullWidth * .75;
    main.css('padding-bottom', paddBottom);

    var thumbWidth = thumb.width();
    var thumbBottom = thumbWidth * .75;
    thumb.css('padding-bottom', thumbBottom);
}

    aspectRatioFix('.full-img', '.img-box');

I get the error "Uncaught TypeError: main.width is not a function"

Is there a way to maybe loop through my function to take care of both parts of my script instead of just duplicating what I have? Thanks!

Upvotes: 0

Views: 61

Answers (4)

Prakash Sundar
Prakash Sundar

Reputation: 40

function aspectRatioFix(main, thumb) { 
    var fullWidth = main.width(); 
    var paddBottom = fullWidth * .75; 
    main.css('padding-bottom', paddBottom); 
    var thumbWidth = thumb.width(); 
    var thumbBottom = thumbWidth * .75;
    thumb.css('padding-bottom', thumbBottom);
 } 
 aspectRatioFix($('.full-img'), $('.img-box'));

Upvotes: -1

Tim Vermaelen
Tim Vermaelen

Reputation: 7059

What I can suggest is simply caching your jQuery objects. A simple DOM ready event inside an IIFE which can be copy/pasted into a separate js file:

// IIFE
(function(scope, $){
    // this configuration
    var cfg = {
        cache: {
            fullImg: '.full-img',
            imgBox: '.img-box'
        },
        options: {
            modifier: 0.75,
            css: 'padding-bottom'
        }
    };

    // function declaration
    function aspectRatioFix(elements, options){
        $.each(elements, function(){
           var el = $(this),
               paddBottom = el.width() * options.modifier;
           el.css(options.css, paddBottom);
        });
    }

    // DOM ready to execute
    $(function(){
        var fullImg = $(cfg.cache.fullImg);
        //var imgBox = $(cfg.cache.imgBox);

        aspectRatioFix(fullImg, cfg.options);
        aspectRatioFix($(cfg.cache.imgBox), cfg.options);
    });
}(window, window.jQuery));

The way I refactor things into functional (in this case) and modular approaches is to move every string in the code to cfg object literal. The code becomes more clear to separate.

And to add real quickly: aspectRatioFix($('.a-new-selector'), cfg.options); In case of the accepted answer you'll have to edit the function again while you should avoid that.

Upvotes: 1

ibrahim mahrir
ibrahim mahrir

Reputation: 31682

The function aspectRatioFix is expecting jQuery objects so you'll have to pass in jQuery objects instead of selectors (strings) like this:

aspectRatioFix($('.full-img'), $('.img-box'));

If you have many images and their thumbs and you want to apply the code for all of them then use .each like this:

var $mains = $('.full-img'),
    $thumbs = $('.img-box');

$mains.each(function(index) {
    // this:  is the main image
    // index: is its index so we can access the according thumb from $thumbs

    aspectRatioFix($(this), $($thumbs[index])); // apply the aspectRatioFix on this main image, and on it's thumb from the $thumbs object (both this and $thumbs[index] are node elements so we have to wrap them in a jQuery object using $())
});

Upvotes: 2

Lixus
Lixus

Reputation: 511

You are sending plain strings and not selectors to your function, you would have to do it like this:

function aspectRatioFix(main, thumb) {
    var fullWidth = main.width();
    var paddBottom = fullWidth * .75;
    main.css('padding-bottom', paddBottom);

    var thumbWidth = thumb.width();
    var thumbBottom = thumbWidth * .75;
    thumb.css('padding-bottom', thumbBottom);
}

aspectRatioFix($('.full-img'), $('.img-box'));

Upvotes: 2

Related Questions