Search code examples
jquerycsswordpressinfinite-carousel

Center active li item inside of jQuery carousel menu that uses Data Cycle FX


I've read through many examples and none seem to address all of my issues. I have a Wordpress generated menu wherein the LI items contain anchor links to content that is controlled with the Data Cycle FX plugin and jQuery. Everything is working as I would like, except that on page refresh/load, I would like to detect which LI item is .active, and have that item be centered within the visible area. (This is mainly an issue if the page is reloaded, as any li.active that is not one of the first 6 items is hidden.) I am thinking that I need to detect the width of the .sub-navigation div and somehow use position() or offset() ... but my attempts have been missing the mark. Any advice is greatly appreciated :-).

Here is my HTML showing the menu structure:

 <body>
 <div class="sub-navigation">
 <div class="prev">
 <a href="#">&lt;</a>
 </div><!--end prev-->
 <div class="next">
 <a href="#">&gt;</a>
 </div><!--end next-->

 <div class="menu-product-pages-container">
 <ul class="subnav cycle-slideshow" data-cycle-fx=carousel data-cycle-timeout=0 data-cycle-easing="linear" data-cycle-carousel-offset="10"data-cycle-next=".next a" data-cycle-prev=".prev a" data-cycle-slides="li">
 <li class="refrigeration-menu"><a href="#refrigeration">Refrigeration</a></li>
 <li class="food-prep-menu"><a href="#food-prep">Food Prep</a></li>
 <li class="cooking-menu"><a href="#cooking">Cooking</a></li>
 <li class="baking-menu"><a href="#baking">baking</a></li>
 <li class="warewashing-menu"><a href="#warewashing">Warewashing</a></li>
 <li class="storage-menu"><a href="#storage">Storage</a></li>
 <li class="food-transport-menu"><a href="#food-transport">Food Transport</a></li>
 <li class="ventilation-menu"><a href="#ventilation">Ventilation</a></li>
 <li class="serving-lines-menu"><a href="#serving-lines">Serving Lines</a></li>
 <li class="conveyors-menu"><a href="#conveyors">Conveyors</a></li>
 </ul></div></div><!--.sub-navigation-->
 </body> 

Here is my CSS:

.sub-navigation {
width: 100%;
float: left;
}
.subnav {
background: #777;
list-style-type: none;
margin: 0px;
padding-left: 0px;
position: relative;
height: 40px;
overflow-x: hidden;
white-space: nowrap;
}
.subnav li {
display: inline;
line-height: 40px;
padding:  0 30px 0 30px;
}
.subnav li a {
color: #000;
display: block;
font-size: 95%;
text-transform:uppercase;
padding-left: 15px;
}
.active {
background-color: #c32d2e;
}
.prev {
color: #ccc;
float: left;
font-size: 185%;
font-weight: bold;
line-height: 40px;
width: 2%;
height: 39px;
}
.prev a, .next a {
color: #ccc;
display: block;
margin: 5px auto 0 auto;
text-align: center;
text-decoration: none;
width: 98%;
}
.next {
float: right;
font-size: 100%;
font-weight: bold;
line-height: 40px;
width: 2%;
height: 39px;
}

And my query:

 $('ul.subnav').each(function(){

 var $active, $content, $links = $(this).find('a');
 $active = $($links.filter('[href="'+location.hash+'"]')[0] || $links[0]);
 $active.parent().addClass('active');
 $content = $($active.attr('href'));  

 $links.not($active).each(function () {
 $($(this).attr('href')).hide();
});
 $("html, body").animate({ scrollTop: 0 }, "fast");
// Bind the click event handler
 $(this).on('click', 'a', function(e){
 $("html, body").animate({ scrollTop: 0 }, "fast");
// Make the old tab inactive.
 $active.parent().siblings().removeClass('active');
 $active.parent().removeClass('active');
 $content.hide();
// Update the variables with the new link and content
 $active = $(this);
 $content = $($(this).attr('href'));
// Make the tab active  
 $active.parent().addClass('active');
 $content.show();
//change url in bar
 window.history.pushState($active);
// Prevent the anchor's default click action
 e.preventDefault();
});
});

It seems like a function similar to this should work to center the .active element in the viewport, but something must be wrong with my understanding/approach:

function scrollMenu(){
$viewportWidth = $('.subnav').width(),
$activeTab = $('ul').find('li.active'),
$elWidth = $activeTab.width(),
$elOffset = $activeTab.offset();
$('.active').parent().scrollTo(elOffset.left - (elWidth/2) - (viewportWidth/2));
}

Solution

  • After much time spent overcomplicating this, I ended up using the simple solution offered in this post: scrolling to li element - jquery.

    Hope it helps anyone who gets stuck in a similar way!