3
\$\begingroup\$

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.addEventListener) {
   window.addEventListener('resize', debounce(function () {
    activateSearch();
    //fade in the slider while loading to prevent that second of ugly formatting
    if ($('#slider').length > 0) {
        $('#slider').delay(700).animate({ opacity: 1 }, 500);
    }
  }, 250));
} else {
    window.attachEvent('resize', debounce(function () {
      activateSearch();
      //fade in the slider while loading to prevent that second of ugly formatting
      if ($('#slider').length > 0) {
         $('#slider').delay(700).animate({ opacity: 1 }, 500);
      }
    }, 250));
}

And the html markup:

<div class="orbit-container">
  <ul id="slider" class="orbit-slides-container" data-orbit>
    <li data-orbit-slide="slide-1" class="active">

      <img src="http://placehold.it/1400x348" alt="" width="1400" height="348">
      <section id="Walrus" class="orbit-caption">        
        <strong>Oh got walrus</strong>
        <div class="slider-content">
          <p>More hence euphemistic oriole let tediously dear repeatedly.</p>
          <a class="read-more" href="#">Read More</a>
        </div>     
      </section>

    </li>
    <li data-orbit-slide="slide-2">

      <img src="http://placehold.it/1400x348" alt="" width="1400" height="348">
      <section id="Overslept" class="orbit-caption">
        <strong>Overslept wiped yikes</strong>
        <div class="slider-content">
           <p>Much supreme quick rakishly tamarin</p>
           <a class="read-more" href="#">Read More</a>
        </div>     
      </section>

   </li>
  </ul>
</div>
\$\endgroup\$
3
\$\begingroup\$

The most important bit here is the resize handler, since it fires many times per scroll.

//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.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.