简体   繁体   中英

Scroll to the top of bootstrap accordion when opened

I've recently been working on a small blog, and would like consecutive blog posts to be accessible from within an accordion (example below). This way, you can quickly skim over post titles, select one which is interesting, and read it. When finished, you can seamlessly go back to skimming without unnecessary menu navigation.

My problem is that once you're done reading a post and click on a second one, I can't get the second post to open at the top, with the title visible. Since you've already scrolled so far down to read the first post, you open 2/3 of the way through the second post. This forces the user to scroll all the way back up to the top of a post which he hasn't read yet. For some reason I can't seem to get anything to work; any guidance would be much appreciated!

UPDATE: It turns out that since I was using the slim version of jQuery, the functions I was trying to use weren't available. Now that I'm over that hurdle, everything compiles but I can't force the page to scroll to the right place.

My closest solution is this, which will scroll back up to the first card-header when a new section is opened (whereas I want the card-header which was clicked).

$(".card-header").click(function (event) {                                      
    $('html, body').animate({                                                   
        scrollTop: $(".card-header").offset().top                               
    }, 300);                                                                    
}); 

What I'm trying to do is logically equivalent to this, but this exact code doesn't scroll at all (it compiles correctly, and replacing $(this) with $(event.target) or $(event.target).parent() doesn't work either).

$(".card-header").click(function(event) {                                                                           
    $('html, body').animate({                                                   
        scrollTop: $(this).offset().top-60                     
    }, 300);  

Here's a minimal working example to reproduce my struggles:

 <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script> <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet"/> <div class="container" id="container"> <div class="card"> <a class="card-header" data-toggle="collapse" href="#sec1">Title1</a> <div id="sec1" class="collapse" data-parent="#container"> <div class="card-body"> lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text </div> </div> </div> <div class="card"> <a class="card-header" data-toggle="collapse" href="#sec2">Title2</a> <div id="sec2" class="collapse" data-parent="#container"> <div class="card-body"> lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text </div> </div> </div> </div> 

Always scroll to the offset-top of the opening collapse element. If the closing collapse if above the opening collapse then subtract the height of the closing collapse from the offset-top of the opening collapse.

 jQuery(function($){ $('.card-header').each(function(){ let $card_header = $(this); let $collapse_element = $card_header.next(); $collapse_element.on('show.bs.collapse', function () { let $card_header_top = $card_header.offset().top; let $visible_collapse = $('.collapse.show'); if($visible_collapse.length){ let $visible_collapse_top = $visible_collapse.offset().top; if($visible_collapse_top < $card_header_top){ $card_header_top -= $visible_collapse.height(); } } $([document.documentElement, document.body]).animate({ scrollTop: $card_header_top }); }); }); }); 
 <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script> <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet"/> <div style="height:30px"></div> <div class="container" id="container"> <div class="card"> <a class="card-header" data-toggle="collapse" href="#sec1">Title1</a> <div id="sec1" class="collapse" data-parent="#container"> <div class="card-body"> lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text </div> </div> </div> <div class="card"> <a class="card-header" data-toggle="collapse" href="#sec2">Title2</a> <div id="sec2" class="collapse" data-parent="#container"> <div class="card-body"> lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text lots and lots of text </div> </div> </div> </div> 

I added the id to the div tag from <div class="card"> to <div class="card" id="div2"> and add javascrip:

$(".card-header").click(function () {
  $('html, body').animate({
    scrollTop: $("#div2").offset().top
  }, 2000);
});

It work for me. You don't need to override everything.

Have use in event

  $(document).ready(function () { $("html, body").animate({ scrollTop: 0 }, 600); }); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> 

Have fun

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM