L84
L84

Reputation: 46308

Scroll to Accordion Item Top Once Open (Foundation Framework)

I'm using ZURB Foundation (v6) Accordions.

When an accordion opens, I want to scroll the page to be at the top of that accordion item. I can run this code:

$("#arf").on("down.zf.accordion", function() {
   $('html,body').animate({scrollTop: $(this).offset().top}, 'slow');
});

Of course, this scrolls the page to the top of the accordion, not the accordion item. How would I modify this code to scroll to the accordion's item when it opens?

Upvotes: 5

Views: 2975

Answers (4)

ReynBargz
ReynBargz

Reputation: 1

You could use the below script, im also using foundation 6 accordion, this will work also if you have multiple accordions on single page. Thanks

jQuery(".accordion-title").click(function() {
    var $this = this;
    setTimeout(function(){
        jQuery('html,body').animate({scrollTop: jQuery($this).closest('.accordion').find('.is-active').offset().top}, 'slow');
    }, 250);
}); 

Upvotes: 0

I first used the solution posted by @L84 then I thought of this one.

In the code below, $active references the currently active accordion item (Note: the reference is stored each time an accordion is opened rather than when the accordion title is clicked). When a new title is clicked, $active is the item that will be closed. We need to know its height in advance.

For the newly active accordion item to be properly positioned, the height of that previously active item has to be subtracted from the viewport's scrolling position -- note that this in necessary only if the newly active item is located further down.

$(function () {
  var $active;

  $(".accordion").on("click", ".accordion-title", function () {
    var itemIndexNew = $(".accordion-item").index($(this).parent());
    var itemIndexOld = ($active ? $(".accordion-item").index($active) : null);
    if (itemIndexOld !== null && itemIndexOld < itemIndexNew) {
      $("html, body").scrollTop($(window).scrollTop() - $active.height());
    }
  });

  $(".accordion").on("down.zf.accordion", function(e) {
    $active = $(".accordion").find(".accordion-item.is-active");
  });

  $(document).foundation();
});

Upvotes: 0

L84
L84

Reputation: 46308

Here is the solution that I found that works. This works for version 6 of Foundation for Sites.

$("#form-selector").on("up.zf.accordion", function(event) {
    setTimeout(function(){
        $('html,body').animate({scrollTop: $('.is-active').offset().top}, 'slow');
    }, 250); //Adjust to match slideSpeed
}); 

The setTimeout is used because of the slideSpeed of the accordion. If you do not use setTimeout it scrolls the moment down.zf.accordion fires thus scrolling to the wrong position.

You can also us down.zf.accordion in place of up.zf.accordion, however, if you use down.zf.accordion, it will fire once the page loads (as the accordion is initialized and opens) and scrolls to the accordion item. This is unwanted in my case but may be desired in certain case.

Upvotes: 3

paulgoblin
paulgoblin

Reputation: 157

You could attach your own click listeners to each accordion <a> tag and scroll to the top of that tag on click. Eg.

JS

$('.accordionBtn').on('click', function(event) {
   $('html,body').animate({scrollTop: $(event.target).offset().top}, 'slow');
});)

CSS

<ul class="accordion" data-accordion>
  <li class="accordion-navigation">
    <a class="accordionBtn" href="#panel1a">Accordion 1</a>
    <div id="panel1a" class="content active">
      Panel 1. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
    </div>
  </li>
  <li class="accordion-navigation">
    <a class="accordionBtn" href="#panel2a">Accordion 2</a>
    <div id="panel2a" class="content">
      Panel 2. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
    </div>
  </li>
  <li class="accordion-navigation">
    <a class="accordionBtn" href="#panel3a">Accordion 3</a>
    <div id="panel3a" class="content">
      Panel 3. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
    </div>
  </li>
</ul>

Upvotes: 1

Related Questions