Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bootstrap accordion, scroll to top of active (open) accordion on click?

I'm making a responsive site using Bootstrap and it contains accordions with a large amount of text, when you read to the bottom and click the next accordion, the large amount of text is collapsed and I'm left at the bottom of the page.

I found this useful code from Bootstrap accordion scroll to top of active panel heading but it scrolls to the top of all the accordions, not the specific one that is open.

JS

$(function () {     $('#accordion').on('shown.bs.collapse', function (e) {         var offset = $('.panel.panel-default > .panel-collapse.in').offset();         if(offset) {             $('html,body').animate({                 scrollTop: $('.panel-heading').offset().top -20             }, 500);          }     });  }); 

How can this code be modified to scroll to the top of the currently active accordion?

HTML

<div class="panel-group custom-padding no-sides" id="accordion">                     <div class="panel panel-default">         <a data-toggle="collapse" data-parent="#accordion" href="#collapse1">             <div class="panel-heading custom-padding">                 <h4 class="panel-title text-uppercase">Short synopsis <i class="fa fa-chevron-down pull-right"></i></h4>             </div>         </a>         <div id="collapse1" class="panel-collapse collapse">             <div class="panel-body">                 <p id="game-deck"></p>             </div>         </div>     </div>                            <div class="panel panel-default">         <a data-toggle="collapse" data-parent="#accordion" href="#collapse2">             <div class="panel-heading custom-padding">                 <h4 class="panel-title text-uppercase">Concepts <i class="fa fa-chevron-down pull-right"></i></h4>             </div>         </a>         <div id="collapse2" class="panel-collapse collapse">             <div class="panel-body">                 <ul class="whatever" id="game-concepts"></ul>             </div>         </div>     </div>                           <div class="panel panel-default">         <a data-toggle="collapse" data-parent="#accordion" href="#collapse3">             <div class="panel-heading custom-padding">                 <h4 class="panel-title text-uppercase">Themes <i class="fa fa-chevron-down pull-right"></i></h4>             </div>         </a>             <div id="collapse3" class="panel-collapse collapse">             <div class="panel-body" id="game-themes"></div>         </div>     </div>      <div class="panel panel-default">         <a data-toggle="collapse" data-parent="#accordion" href="#collapse4">             <div class="panel-heading custom-padding">                 <h4 class="panel-title text-uppercase">Notable locations<i class="fa fa-chevron-down pull-right"></i></h4>             </div>         </a>             <div id="collapse4" class="panel-collapse collapse">             <div class="panel-body" id="game-locations"></div>         </div>     </div>      <div class="panel panel-default">         <a data-toggle="collapse" data-parent="#accordion" href="#collapse5">             <div class="panel-heading custom-padding">                 <h4 class="panel-title text-uppercase">Notable characters<i class="fa fa-chevron-down pull-right"></i></h4>             </div>         </a>             <div id="collapse5" class="panel-collapse collapse">             <div class="panel-body" id="game-characters"></div>         </div>     </div>      <div class="panel panel-default">         <a data-toggle="collapse" data-parent="#accordion" href="#collapse6">             <div class="panel-heading custom-padding">                 <h4 class="panel-title text-uppercase">Full description <i class="fa fa-chevron-down pull-right"></i></h4>             </div>         </a>             <div id="collapse6" class="panel-collapse collapse">             <div class="panel-body" id="game-description"></div>         </div>     </div> </div> 
like image 872
user3574766 Avatar asked Mar 14 '16 16:03

user3574766


People also ask

How do I keep my bootstrap accordion open?

Always open Omit the data-bs-parent attribute on each .accordion-collapse to make accordion items stay open when another item is opened.

How do you prevent a page scroll when collapse or expand elements?

I've found that adding an href="#0" helps resolve this issue.

How do you collapse an accordion by default?

To create an accordion that is collapsed by default, we need to set the 'active' property of the jQuery Accordion as false. Syntax: $("#demoAccordion"). accordion({ collapsible: true, active: false});

What is the use of accordion in bootstrap?

The Bootstrap accordion is a component that organizes content within collapsable items. Accordion allows the display of only one collapsed item at a time. Accordions can toggle through a number of text blocks with a single click, and that greatly enhances the UX of your project.


2 Answers

You can animate the scroll by getting the top of the 'target element' and then calling animate on the body..

$('html, body').animate({     scrollTop: $("#target-element").offset().top }, 1000); 

modifying it to be something like this will help you achieve what you are after

$('.panel-collapse').on('shown.bs.collapse', function (e) {     var $panel = $(this).closest('.panel');     $('html,body').animate({         scrollTop: $panel.offset().top     }, 500);  });  

source: http://www.abeautifulsite.net/smoothly-scroll-to-an-element-without-a-jquery-plugin-2/

complementary fiddle: https://jsfiddle.net/hjugdwbp/


Edit: 2018-05-25

Bootstrap 4 Example

Using the accordion example at: https://getbootstrap.com/docs/4.0/components/collapse/#accordion-example I have modified the code to support cards.

$('.collapse').on('shown.bs.collapse', function(e) {   var $card = $(this).closest('.card');   $('html,body').animate({     scrollTop: $card.offset().top   }, 500); }); 

Fiddle: https://jsfiddle.net/agpkc4v2/1/


Edit: 2019-07-18

I made it 'prettier'...

Bootstrap 3

https://jsfiddle.net/erutfgvn/

$('.panel-collapse').on('show.bs.collapse', function(e) {   var $panel = $(this).closest('.panel');   var $open = $(this).closest('.panel-group').find('.panel-collapse.in');      var additionalOffset = 0;   if($panel.prevAll().filter($open.closest('.panel')).length !== 0)   {         additionalOffset =  $open.height();   }   $('html,body').animate({     scrollTop: $panel.offset().top - additionalOffset   }, 500); }); 

Bootstrap 4

https://jsfiddle.net/9p7f0hut/

$('.collapse').on('show.bs.collapse', function(e) {   var $card = $(this).closest('.card');   var $open = $($(this).data('parent')).find('.collapse.show');      var additionalOffset = 0;   if($card.prevAll().filter($open.closest('.card')).length !== 0)   {         additionalOffset =  $open.height();   }   $('html,body').animate({     scrollTop: $card.offset().top - additionalOffset   }, 500); }); 

Edit: 2021-04-20

Bootstrap 5

https://jsfiddle.net/hLzg0n2y/2/

$('.collapse').on('shown.bs.collapse', function(e) {   var $card = $(this).closest('.accordion-item');   var $open = $($(this).data('parent')).find('.collapse.show');      var additionalOffset = 0;   if($card.prevAll().filter($open.closest('.accordion-item')).length !== 0)   {         additionalOffset =  $open.height();   }   $('html,body').animate({     scrollTop: $card.offset().top - additionalOffset   }, 500); }); 
like image 108
Michael Coxon Avatar answered Sep 26 '22 11:09

Michael Coxon


Update 2021

As of Bootstrap 5, jQuery is no longer required. Here is a vanilla JavaScript solution of scrolling to the top of the open accordion item...

const accordionItems = document.querySelectorAll('.accordion-collapse') const acc = document.getElementById('accordionExample')  accordionItems.forEach((el)=>{     el.addEventListener('shown.bs.collapse',(e)=>{         var scrollOffset = acc.scrollTop + el.parentNode.offsetTop         acc.scroll({             top: scrollOffset,             left: 0,              behavior: 'smooth'         })     }) }) 

Demo

like image 21
Zim Avatar answered Sep 25 '22 11:09

Zim