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

眉间皱痕 提交于 2019-12-17 18:35:17

问题


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.

$(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>

回答1:


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);
});



回答2:


I am working on a project that needed the same functionality. Came up with the following code. I added the variables for clarification:

$('#accordion').on('shown.bs.collapse', function (e) {

var panelHeadingHeight = $('.panel-heading').height();
var animationSpeed = 500; // animation speed in milliseconds
var currentScrollbarPosition = $(document).scrollTop();
var topOfPanelContent = $(e.target).offset().top;

if ( currentScrollbarPosition >  topOfPanelContent - panelHeadingHeight) {
    $("html, body").animate({ scrollTop: topOfPanelContent - panelHeadingHeight }, animationSpeed);
}});


来源:https://stackoverflow.com/questions/35992900/bootstrap-accordion-scroll-to-top-of-active-open-accordion-on-click

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!