I have a series of bootstrap 3 accordion panels with lots of content in them that are almost working... they load collapsed as wanted and open when clicked as they should, collapsing any other open panels in the process; all good...

but when I open Panel 1 and scroll down its content, and then open Panel 2, the Panel 2 content loads "upwards" past the top of the visible browser window; meaning the user has to scroll up to see the top of Panel 2. Frustrating!

I want Panel 2 to load so the top of it is visible within the browser window.

Here's a JSFiddle

<!-- language: lang-html -->
<div class="panel-group" id="accordion">
    <!-- first panel -->
    <div class="panel panel-default">
        <div class="panel-heading"> 
            <span class="strong">
                <a data-toggle="collapse" data-parent="#accordion"
                   href="#collapseOne" id="predict">
                   Gettysburg <span class="caret"></span>
                </a>
            </span>
        </div>
        <div id="collapseOne" class="panel-collapse collapse">
            <div class="panel-body">
                <!--LOTS OF CONTENT - replaced with image-->
                <img src="http://i.imgur.com/AMhADP1.png" />
            </div>
        </div>
    </div>
    
    <!-- second panel -->
    <div class="panel panel-default">
        <div class="panel-heading">
            <span class="strong">
                <a data-toggle="collapse" data-parent="#accordion" href="#collapseTwo" id="aries">
                    Background <span class="caret"></span>
                </a>
            </span>
        </div>
        <div id="collapseTwo" class="panel-collapse collapse">
            <div class="panel-body">
                <!--LOTS OF CONTENT - replaced with image-->
                <img src="http://imgur.com/j98Q0H8.png" />
            </div>
        </div>
    </div>
</div>

Any ideas on how I can fix this, please?

The browser will always try to maintain its current position within the page, even when you collapse / show large elements that could disrupt that position.

You can solve this with a two part approach suggested by Gokhan:

  1. Tap into the event handler for the accordion's shown event
  2. Scroll to the top of the current panel once it's displayed.

The first part is pretty simple. From the Collapse Events Docs we'll find:

shown.bs.collapse - This event is fired when a collapse element has been made visible to the user (will wait for CSS transitions to complete).

We'll listen for this event like this:

<!-- language: lang-js -->
$('#accordion').on('shown.bs.collapse', function (e) {
   var id = $(e.target).prev().find("[id]")[0].id;
   navigateToElement(id);
})

In the shown event I've called a function navigateToElement and passed in the id from header of the visible panel. The navigate function will scroll to the id's position using jquery's animate:

<!-- language: lang-js -->
function navigateToElement(id) {
    $('html, body').animate({
        scrollTop: $("#" + id).offset().top
    }, 1000);
}

Working Demo in jsFiddle