I have image slider with thumbnails, simple one where I account for left and right arrow clicks that show respective images and thumbnail clicks that load related image. Functions have a lot in common and I'm trying to figure out how to put them into one and use it for all 3 different events, but am having trouble as thumbnail one is slightly different.
//Handle next-image click on product single page
$('.images').on('click', '#next-image', function(e) {
e.preventDefault();
var current = $('.thumbnail-link.first');
//Check if thumbnail is last, if it is make first thumbnail next
if(current.next().hasClass('thumbnail-link')) {
next = current.next('.thumbnail-link');
} else {
next = $('.thumbnail-link').first();
}
//Grab image src from data-image attribute
var image = next.data('image');
$('.woocommerce-main-image')
.find('img')
.animate({
opacity: 0
}, 300, function() {
$(this).attr('src', image);
$(this).animate({opacity: 1}, 300);
})
current.removeClass('first');
next.addClass('first');
});
//Handle prev-image click on product single page
$('.images').on('click', '#prev-image', function(e) {
e.preventDefault();
var current = $('.thumbnails .first');
//Check if thumbnail is last, if it is make first thumbnail next
if(current.prev().hasClass('thumbnail-link')) {
prev = current.prev('.thumbnail-link');
} else {
prev = $('.thumbnail-link').last();
}
//Grab image src from data-image attribute
var image = prev.data('image');
$('.woocommerce-main-image')
.find('img')
.animate({
opacity: 0
}, 300, function() {
$(this).attr('src', image);
$(this).animate({opacity: 1}, 300);
})
current.removeClass('first');
prev.addClass('first');
});
//Handle click on thumbnail
$('.thumbnails').on('click', '.thumbnail-link', function(e) {
e.preventDefault();
var current = $('.thumbnail-link.first'),
image = $(this).data('image');
$('.woocommerce-main-image')
.find('img')
.animate({
opacity: 0
}, 300, function() {
$(this).attr('src', image);
$(this).animate({opacity: 1}, 300);
})
current.removeClass('first');
$(this).addClass('first');
});
1 Answer 1
A lot of present code can be made reusable.
I have made the necessary changes and created a single reusable function handleEvent
// Handle next-image click on product single page
var handleEvent = function(e, currentClass, linkClass, method) {
e.preventDefault();
var current = $('.' + currentClass + '.first');
var next;
// handles click on thumbnail
if (typeof method == "undefined") {
next = $(this);
} else {
// Handles next-image and prev-image click on product single page
// Check if thumbnail is last, if it is make first thumbnail next
if (current.next().hasClass(linkClass)) {
next = current.next('.' + linkClass);
} else {
next = $('.' + linkClass)[method]();
}
}
// Grab image src from data-image attribute
var image = next.data('image');
$('.woocommerce-main-image')
.find('img')
.animate({
opacity: 0
}, 300, function() {
$(this).attr('src', image);
$(this).animate({
opacity: 1
}, 300);
});
current.removeClass('first');
next.addClass('first');
};
Example of calling this reusable function from three different events is as follows
// Handle next-image click on product single page
$('.images').on('click', '#next-image', function(e) {
handleEvent(e, 'thumbnail-link', 'thumbnail-link', 'first');
});
// Handle prev-image click on product single page
$('.images').on('click', '#prev-image', function(e) {
handleEvent(e, 'thumbnails', 'thumbnail-link', 'last');
});
// Handle click on thumbnail
$('.thumbnails').on('click', '.thumbnail-link', function(e) {
handleEvent(e, 'thumbnail-link');
});