Bootstrap accordion scroll to top of active panel

2019-03-18 23:25发布

问题:

I'm looking for a code that scrolls up to the top of the currently active panel heading of my bootstrap 3 html/css accordion. The closest solution I've found on stackoverflow is the snippet of js below.

This snippet works fairly well, but when a panel heading gets clicked the page scrolls such that the very top of the panel content is flush with the top of the screen. Is there a way to modify this so that the scrolling effect will result in the panel "heading" (as opposed to the top of panel content area) being visible at the top of the screen?

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

Let me know if I should be sharing the bootstrap accordion html as well.

回答1:

I used this and it works fine you can adjust the -20 after the .offset().top if you need to tweak it up or down a little.

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


回答2:

This is to target the specific .panel-heading clicked as per James Wilson's comment on the accepted answer.

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

All I changed from gigelsmith's accepted answer is 'var offset' and the scrollTop's target.



回答3:

I couldn't get the answer above to work, perhaps I'm missing something but I can't see how the scrollTop line above relates to the currently opened accordion item so used the following code instead. Hope it helps someone else:

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


回答4:

Always animate looks a bit too much so this is my version to only do the job when heading is over the visible part. (note that I use a data-accordion-focus to apply the fix)

$('[data-accordion-focus]').on('shown.bs.collapse', function (e) {
    var headingTop = $(e.target).prev('.panel-heading').offset().top - 5;
    var visibleTop = $(window).scrollTop();
    if (headingTop < visibleTop) {
        $('html,body').animate({
            scrollTop: headingTop
        }, 500);
    }
});



回答5:

By using .panel-default as selector of .on(), you can scroll to the active panel.

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