patternjavascriptMinor
How could I have approached this responsive image gallery differently?
Viewed 0 times
thisdifferentlyimagegallerycouldresponsiveapproachedhowhave
Problem
This gallery uses the Orbit gallery from the Foundation framework (version 3). I've set it up so that on smaller screens it appears as an accordion.
It works just fine, but is there a more concise way this could've been written? Perhaps in an object oriented way?
The script:
```
function activateSlider() {
if (window.Foundation && window.matchMedia) {
// Establishing media check
widthCheck = window.matchMedia("(max-width: 767px)");
if (widthCheck.matches) {
$('.orbit-container').after($('.orbit-timer'));
$('#slider, #slider li').attr('style', '');
$('#slider').removeClass('orbit-slides-container').removeAttr('data-orbit').addClass('accordion-container');
$('#slider li').removeAttr('data-orbit-slide').removeClass('active');
$('.orbit-container > a, #slider li .slider-content').hide();
$('#slider li:not(.active) .slider-content').css('display', 'none');
//Init accordion click functions
$('#slider li').unbind().bind('click', function(){
$(this).toggleClass('active').siblings().removeAttr('class');
$(this).siblings().find('.slider-content').slideUp();
$(this).find('.slider-content').slideToggle();
});
}
else
{
//If accordion styles are present, clean it up
var OrbitStyles = ($('.accordion-container').length === 0);
if (!OrbitStyles) {
$('.orbit-container > a').show();
$('#slider').removeClass('accordion-container');
$('#slider').addClass('orbit-slides-container');
$('#slider').attr('data-orbit', '');
$('.orbit-bullets-container').before($('.orbit-timer'));
$('.orbit-timer').removeClass('paused');
}
//Then set it up for the slider
$('.slider-content').show();
$('#slider li:first-child').addClass('active').siblings().removeAttr('class');
}
}
}
//Run the script
$(function(){
activateSlider();
});
//Run the script on resize
if (window.addEventList
It works just fine, but is there a more concise way this could've been written? Perhaps in an object oriented way?
The script:
```
function activateSlider() {
if (window.Foundation && window.matchMedia) {
// Establishing media check
widthCheck = window.matchMedia("(max-width: 767px)");
if (widthCheck.matches) {
$('.orbit-container').after($('.orbit-timer'));
$('#slider, #slider li').attr('style', '');
$('#slider').removeClass('orbit-slides-container').removeAttr('data-orbit').addClass('accordion-container');
$('#slider li').removeAttr('data-orbit-slide').removeClass('active');
$('.orbit-container > a, #slider li .slider-content').hide();
$('#slider li:not(.active) .slider-content').css('display', 'none');
//Init accordion click functions
$('#slider li').unbind().bind('click', function(){
$(this).toggleClass('active').siblings().removeAttr('class');
$(this).siblings().find('.slider-content').slideUp();
$(this).find('.slider-content').slideToggle();
});
}
else
{
//If accordion styles are present, clean it up
var OrbitStyles = ($('.accordion-container').length === 0);
if (!OrbitStyles) {
$('.orbit-container > a').show();
$('#slider').removeClass('accordion-container');
$('#slider').addClass('orbit-slides-container');
$('#slider').attr('data-orbit', '');
$('.orbit-bullets-container').before($('.orbit-timer'));
$('.orbit-timer').removeClass('paused');
}
//Then set it up for the slider
$('.slider-content').show();
$('#slider li:first-child').addClass('active').siblings().removeAttr('class');
}
}
}
//Run the script
$(function(){
activateSlider();
});
//Run the script on resize
if (window.addEventList
Solution
The most important bit here is the resize handler, since it fires many times per scroll.
As for your
//Run on document ready
$(function () {
// Cache the slider jQuery object
var slider = $('#slider');
// Pass in the existing reference. Explanation after the code
activateSlider(slider);
// Move out the debouncing function outside the resize handler
// so that the function isn't recreated on every risize call
function debounceAction() {
activateSearch();
//Personal preference. The "early return" looks better since
// it avoids any additional indention
if (!slider.length) return;
slider.delay(700).animate({opacity: 1}, 500);
}
// Since you use jQuery, use it to abstract the resize function instead.
$(window).on('resize', function () {
// And all the handler's got to do is call debounce
debounce(debounceAction, 250);
});
});As for your
activateSlider, you should cache the fetched DOM elements into variables and reuse them when necessary. Each time you do something like $('.slider'), it looks for elements with class slider. Caching them avoids this searching. I have already done it with $('#slider') by fetching it once, and passing it into activateSlider.Code Snippets
//Run on document ready
$(function () {
// Cache the slider jQuery object
var slider = $('#slider');
// Pass in the existing reference. Explanation after the code
activateSlider(slider);
// Move out the debouncing function outside the resize handler
// so that the function isn't recreated on every risize call
function debounceAction() {
activateSearch();
//Personal preference. The "early return" looks better since
// it avoids any additional indention
if (!slider.length) return;
slider.delay(700).animate({opacity: 1}, 500);
}
// Since you use jQuery, use it to abstract the resize function instead.
$(window).on('resize', function () {
// And all the handler's got to do is call debounce
debounce(debounceAction, 250);
});
});Context
StackExchange Code Review Q#48177, answer score: 3
Revisions (0)
No revisions yet.