AngularJS / ui-bootstrap accordion - scroll to top of active (open) accordion on click

耗尽温柔 提交于 2021-01-27 04:18:31

问题


When a panel is opened I need to have it scroll back to the ".panel-title" of the one that was just clicked. I know that I can create a directive to do this such as (got this from this site):

.directive( 'scrollTop', scrollTop );

  function scrollTop() {
      return {
          restrict: 'A',
          link: link
      };
  }

  function link( $scope, element ) {
      $scope.collapsing = false;
      $scope.$watch( function() {
          return $(element).find( '.panel-collapse' ).hasClass( 'collapsing' );
      }, function( status ) {
          if ( $scope.collapsing && !status ) {
              if ( $(element).hasClass( 'panel-open' ) ) {
                  $( 'html,body' ).animate({
                      scrollTop: $(element).offset().top - 20
                  }, 500 );
              }
          }
          $scope.collapsing = status;
      } );
  }

And in the HTML I was supposed to use:

<div uib-accordion-group is-open="status.openPanel" scroll-top></div>

But this does not seem to work. When you click the second panel it opens the first and second panel and it never even scrolls to the top when opening the third one.

I just need it to scroll back to the ".panel-title" of the panel that was clicked. I think it is pretty ridiculous that this seems to be so difficult to do when a lot of the time the panel content can get pretty long and I think most people would want to scroll to the top of the info when a panel is opened.

I have seen other posts on here but they don't seem to be dealing with AngularJS. I am using " ui-bootstrap-tpls-2.1.3 "

EDIT - Here is a Plunker to play with if you would like.

Any help is greatly appreciated.


回答1:


this may be a quick and dirty method, but works flawless

angular.module('ui.bootstrap.demo', ['ngAnimate', 'ui.bootstrap'])
  .controller('AccordionDemoCtrl', function($scope) {
    $scope.oneAtATime = true;

    $scope.groups = [{
      title: 'Dynamic Group Header - 1',
      content: 'Dynamic Group Body - 1'
    }, {
      title: 'Dynamic Group Header - 2',
      content: 'Dynamic Group Body - 2 Dynamic Group Header - 2 Dynamic Group Header - 2 Dynamic Group Header - 2 Dynamic Group Header - 2 Dynamic Group Header - 2'
    }];

    $scope.items = ['Item 1', 'Item 2', 'Item 3'];

    $scope.addItem = function() {
      var newItemNo = $scope.items.length + 1;
      $scope.items.push('Item ' + newItemNo);
    };

    $scope.status = {
      isFirstOpen: true,
      isFirstDisabled: false
    };

    //scrolling  
    var accordion = $('.accordion'), timeOut;
    accordion.on('click', '.panel-heading', function(e) {
      if(e.target.nodeName != 'SPAN') return;
      var element = this;
      clearTimeout(timeOut);
      //since we dont know the exact offsetTop for dynamic content
      //using timeout 350 which let angular complete its render
      timeOut = setTimeout(function() {
        accordion.animate({
          scrollTop: element.offsetTop -2
        }, 300);
      }, 350);
    });
  });
.accordion {
  max-height: 220px;
  overflow: auto;
  padding: 2px; 8px 0 0;
}
*:focus { outline: none !important; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.6/angular.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.6/angular-animate.js"></script>
<script src="https://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.14.0.js"></script>
<link href="https://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
<div ng-app="ui.bootstrap.demo">
  <div ng-controller="AccordionDemoCtrl">
    <script type="text/ng-template" id="group-template.html">
      <div class="panel {{panelClass || 'panel-default'}}">
        <div class="panel-heading">
          <h4 class="panel-title" style="color:#fa39c3">
          <a href tabindex="0" class="accordion-toggle" ng-click="toggleOpen()" uib-accordion-transclude="heading"><span
            ng-class="{'text-muted': isDisabled}">{{heading}}</span></a>
        </h4>
        </div>
        <div class="panel-collapse collapse" uib-collapse="!isOpen">
          <div class="panel-body" style="text-align: right" ng-transclude></div>
        </div>
      </div>
    </script>

    <div class="accordion">
      <uib-accordion close-others="oneAtATime">
        <uib-accordion-group heading="Static Header, initially expanded" is-open="status.isFirstOpen" is-disabled="status.isFirstDisabled">
          This content is straight in the template.
        </uib-accordion-group>
        <uib-accordion-group heading="{{group.title}}" ng-repeat="group in groups">
          {{group.content}}
        </uib-accordion-group>
        <uib-accordion-group heading="Dynamic Body Content">
          <p>The body of the uib-accordion group grows to fit the contents</p>
          <button type="button" class="btn btn-default btn-sm" ng-click="addItem()">Add Item</button>
          <div ng-repeat="item in items">{{item}}</div>
        </uib-accordion-group>
        <uib-accordion-group heading="Custom template" template-url="group-template.html">
          Hello
        </uib-accordion-group>
        <uib-accordion-group heading="Delete account" panel-class="panel-danger">
          <p>Please, to delete your account, click the button below</p>
          <p>Please, to delete your account, click the button below</p>
          <p>Please, to delete your account, click the button below</p>
          <button class="btn btn-danger">Delete</button>
        </uib-accordion-group>
        <uib-accordion-group is-open="status.open">
          <uib-accordion-heading>
            I can have markup, too! <i class="pull-right glyphicon" ng-class="{'glyphicon-chevron-down': status.open, 'glyphicon-chevron-right': !status.open}"></i>
          </uib-accordion-heading>
          This is just some content to illustrate fancy headings.
        </uib-accordion-group>
      </uib-accordion>
    </div>
  </div>
</div>


来源:https://stackoverflow.com/questions/39152485/angularjs-ui-bootstrap-accordion-scroll-to-top-of-active-open-accordion-on

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