【问题标题】:Bootstrap accordion, scroll to top of active (open) accordion on click?Bootstrap手风琴,点击时滚动到活动(打开)手风琴的顶部?
【发布时间】:2016-06-29 19:23:18
【问题描述】:

我正在使用 Bootstrap 制作一个响应式站点,它包含带有大量文本的手风琴,当您阅读到底部并单击下一个手风琴时,大量文本被折叠并且我留在底部页面。

我从Bootstrap accordion scroll to top of active panel heading 找到了这个有用的代码,但它会滚动到所有手风琴的顶部,而不是打开的特定手风琴。

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

如何修改此代码以滚动到当前活动的手风琴顶部?

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>

【问题讨论】:

    标签: javascript jquery twitter-bootstrap accordion


    【解决方案1】:

    您可以通过获取“目标元素”的顶部然后在 body 上调用 animate 来为滚动设置动画..

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

    将其修改为类似的内容将帮助您实现目标

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

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

    补充小提琴:https://jsfiddle.net/hjugdwbp/


    编辑:2018-05-25

    引导程序 4 示例

    使用手风琴示例:https://getbootstrap.com/docs/4.0/components/collapse/#accordion-example 我已经修改了代码以支持卡片。

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

    小提琴:https://jsfiddle.net/agpkc4v2/1/


    编辑:2019-07-18

    我让它“更漂亮”了……

    引导程序 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);
    });
    

    引导程序 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);
    });
    

    编辑:2021-04-20

    引导程序 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);
    });
    

    【讨论】:

    • 如果没有为每个具有唯一 ID 的面板提供不同的功能,我看不出这将如何工作?
    • 谢谢你,这是最有帮助的
    • 我已将.panel-group 包裹在 slimScroll 中,如何达到同样的效果?
    • 我加了一个return false;在动画下方,因为我嵌套了引导折叠面板,并且它冒泡并移动两次,将用户留在父面板上,但否则这对我有用,正是我想要的!
    • @JDW 我已经更新了答案。它不像其他人那么顺利,但它是功能性的。我会处理平滑度。
    【解决方案2】:

    我正在开发一个需要相同功能的项目。想出了以下代码。我添加了变量以进行澄清:

    $('#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);
    }});
    

    【讨论】:

    • 真的很喜欢这个答案,具体取决于您的用例。接受的答案每次都会有效地滚动,而只有在您看不到面板/按钮触发器的顶部时才会滚动。在大多数情况下,恕我直言,这是一个更好的用户体验。需要注意的几个小调整/注意事项:(1)在 safari/ipad 上使用 .scrollTop 时要小心(2)如果您有一个粘性标题,您需要将其添加到正在进行的“减法”中。 (3) 您可能希望在此示例中添加比 panelHeadingHeight 更多的内容,例如 *2,以便它们在按钮上方获得一点视觉空间。
    【解决方案3】:

    2021 年更新

    Bootstrap 5 开始,不再需要 jQuery。这是滚动到打开的手风琴项目顶部的普通 JavaScript 解决方案...

    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

    【讨论】:

    • Class accordion-collapse 可能是可选的。也许这样更好:accordionItems = acc.querySelectorAll('.collapse')
    • window.scroll方法替换acc.scroll
    【解决方案4】:
    $('.accordion-button').on("click",function(event){
        var accordion = $(this).parent().parent().parent();
        window.setTimeout(function(){
          $('body,html').stop().animate({ scrollTop: accordion[0].scrollHeight}, 1000);
        },100)
      }
    

    当用户点击手风琴箭头按钮时,上面的代码会执行以下步骤:-

    1.一个手风琴变量被设置为手风琴按钮的类“.accordion”的父节点。

    2.accordion[0].scrollHeight - 找到打开的手风琴的滚动高度。

    3.使用scrollTop的动画选项将页面移动到手风琴的滚动高度。

    4. 为确保在手风琴打开后执行第 2 步和第 3 步,setTimeout 函数用于在手风琴打开后对代码进行计时。如果在你的情况下手风琴体更长,那么你可能会相应地更改值。目前在上面的代码中它是 100。

    【讨论】:

    • 请在代码中添加解释以获得更完整和详细的答案。
    猜你喜欢
    • 2017-01-02
    • 2018-12-23
    • 2017-11-01
    • 1970-01-01
    • 2021-06-26
    • 2014-03-24
    • 2016-10-11
    • 2017-10-26
    • 1970-01-01
    相关资源
    最近更新 更多