Reputation:
I have these 3 jQuery functions that basically do the same thing, but they are a tiny bit different (width of window, and class that is removed/toggled)
I need the functionality of all these 3 functions, but want to somehow combine them/shorten them into one function. I've tried to but my code keeps breaking Can anyone help to shorten them?
Here are the 3 functions
jQuery(document).ready(function($) {
$('.exampleimg').click(function() {
$('.about').hide(600);
if (($(window).width() > 670) && ($(this).hasClass('exampleimgopen'))) {
$(this).removeClass('exampleimgopen');
} else if ($(window).width() > 670) {
$('.exampleimg').removeClass('exampleimgopen');
$(this).addClass('exampleimgopen');
}
});
});
jQuery(document).ready(function($) {
$('.exampleimg').click(function() {
$('.about').hide(600);
if (($(window).width() < 670) && ($(this).hasClass('exampleimgopen2'))) {
$(this).removeClass('exampleimgopen2');
} else if ($(window).width() < 670) {
$('.exampleimg').removeClass('exampleimgopen2');
$(this).addClass('exampleimgopen2');
}
});
});
jQuery(document).ready(function($) {
$('.exampleimg').click(function() {
$('.about').hide(600);
if (($(window).width() < 540) && ($(this).hasClass('exampleimgopen3'))) {
$(this).removeClass('exampleimgopen3');
} else if ($(window).width() < 540) {
$('.exampleimg').removeClass('exampleimgopen3');
$(this).addClass('exampleimgopen3');
}
});
});
Upvotes: 0
Views: 84
Reputation: 35501
I need the functionality of all these 3 functions, but want to somehow combine them/shorten them into one function.
Generally, a good approach when refactoring similar functions is to create a single factory function that will take your variable data as arguments and return a function that has access to that data via its closure.
function myFactory(conditionFunc, windowWidth, cssClass) {
return function() {
$('.about').hide(600);
var windowCondition = conditionFunc($(window).width(), windowWidth);
if (windowCondition && ($(this).hasClass(cssClass))) {
$(this).removeClass(cssClass);
} else if (windowCondition) {
$('.exampleimg').removeClass(cssClass);
$(this).addClass(cssClass);
}
}
}
Then you can call this function 3 times to build your functions:
// helper methods that will perform '<' or '>' on window width
var lessThan = function(a, b) { return a < b; };
var greaterThan = function(a, b) { return a > b; };
var func1 = myFactory(greaterThan, 670, 'exampleimgopen');
var func2 = myFactory(lessThan, 670, 'exampleimgopen2');
var func3 = myFactory(lessThan, 540, 'exampleimgopen3');
Which you can then pass each into their corresponding listeners.
$('.exampleimg').click(func1);
$('.exampleimg').click(func2);
$('.exampleimg').click(func3);
The advantage of doing things this way is that you only write a single function which then creates different versions of your listener callback functions, based on the data you give to it.
Upvotes: 3
Reputation: 4603
I think is maybe closer to what you wanted, although it's unclear what you wanted to have happen when the width was < 540. Might want to use if .. then ... else
instead
jQuery(document).ready(function($) {
$('.exampleimg').click(function() {
var width = $(window).width();
var classes = [];
if (width < 540) {
classes.push('exampleimgopen3');
}
if ($(window).width() < 670) {
classes.push('exampleimgopen2');
}
if ($(window).width() >= 670) {
classes.push('exampleimgopen');
}
classes.forEach(function(class) {
$('.exampleimg').removeClass(class);
if (!$(this).hasClass(class)) {
$(this).addClass(class);
}
});
});
});
Upvotes: 0