Accordion - Scroll to top of open content

36 Views Asked by At

I was provided the following Java script for an accordion menu. How do I add additional code so that when I click on a new accordion menu, it scrolls to the top of that opened content?

For example, after opening a long accordion content I get pushed towards the bottom of the page and when I click on the accordion menu the content opens above and cannot be seen.

Below is the java script provided. Thank you for your help.

Java Script Provided
<script src="//code.jquery.com/jquery-3.5.1.js"></script>
          <script>
            $(document).ready(function() {
              $(document).on("scroll", onScroll);
              //smoothscroll
              $('a[href^="#"]').on('click', function(e) {
                e.preventDefault();
                $(document).off("scroll");
                $('#faq-menu a').each(function() {
                  $(this).removeClass('active');
                })
                $(this).addClass('active');
                var target = this.hash,
                  menu = target;
                $target = $(target);
                $('html, body').stop().animate({
                  'scrollTop': $target.offset().top + 2
                }, 500, 'swing', function() {
                  window.location.hash = target;
                  $(document).on("scroll", onScroll);
                });
              });
            });

            function onScroll(event) {
              var scrollPos = $(document).scrollTop();
              $('#faq-menu a').each(function() {
                var currLink = $(this);
                var refElement = $(currLink.attr("href"));
                if (refElement.position().top <= scrollPos && refElement.position().top + refElement.height() > scrollPos) {
                  $('#faq-menu a').removeClass("active");
                  currLink.addClass("active");
                } else {
                  currLink.removeClass("active");
                }
              });
            }
          </script>
          <script>
            var accItem = document.getElementsByClassName('accordionItem');
            var accHD = document.getElementsByClassName('accordionItemHeading');
            for (i = 0; i < accHD.length; i++) {
              accHD[i].addEventListener('click', toggleItem, false);
            }

            function toggleItem() {
              var itemClass = this.parentNode.className;
              for (i = 0; i < accItem.length; i++) {
                accItem[i].className = 'accordionItem closed';
              }
              if (itemClass == 'accordionItem closed') {
                this.parentNode.className = 'accordionItem open';
              }
            }
          </script>
          <script>
            $(window).scroll(function() {
              var scroll = $(window).scrollTop();
              if (scroll >= 200) {
                $(".menu").addClass("freeze");
              } else {
                $(".menu").removeClass("freeze");
              }
            });
          </script>

1

There are 1 best solutions below

0
KamiSama On

This modification includes the addition of the toggleItem function, which handles the scrolling behavior after expanding an accordion item. When an accordion item is opened, it calculates the offset top position of the clicked heading and scrolls to that position, bringing it into view.

function toggleItem() {
var itemClass = this.parentNode.className;
for (i = 0; i < accItem.length; i++) {
    accItem[i].className = 'accordionItem closed';
}
if (itemClass == 'accordionItem closed') {
    this.parentNode.className = 'accordionItem open';

    // Scroll to the top of the opened content
    var offsetTop = $(this).offset().top;
    $('html, body').animate({
        'scrollTop': offsetTop
    }, 500);
  }
}

Now this is what happened:

In var offsetTop = $(this).offset().top;: $(this) refers to the current element, which is the clicked accordion header (accordionItemHeading). .offset() is a jQuery function that returns an object with the top and left properties of the element relative to the document. .top gets the distance from the top of the document to the top of the current element.The rest is just a simple animation. I hope it helps :)