AngularJS / ui-bootstrap accordion - scroll to top of active (open) accordion on click
打开一个面板时,我需要将其滚动回到刚刚单击的面板的" .panel-title"。我知道我可以创建一个指令来执行此操作,例如(从此站点获得此操作):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | .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; } ); } |
在HTML中,我应该使用:
1 |
但这似乎不起作用。单击第二个面板时,它会打开第一个和第二个面板,打开第三个面板时,它甚至不会滚动到顶部。
我只需要它可以滚动回到所单击面板的" .panel-title"。我认为这很荒谬,因为很多时候面板内容会变得很长,而且似乎很多人都想在面板打开时滚动到信息的顶部。铅>
我在这里看到过其他文章,但它们似乎与AngularJS无关。我正在使用" ui-bootstrap-tpls-2.1.3"
编辑-如果您愿意,这是一个Plunker。
非常感谢您的帮助。
这可能是一种快速而肮脏的方法,但是可以完美地运行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | 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); }); }); |
1 2 3 4 5 6 | .accordion { max-height: 220px; overflow: auto; padding: 2px; 8px 0 0; } *:focus { outline: none !important; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.js"> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.6/angular.js"> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.6/angular-animate.js"> <script src="https://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.14.0.js"> <link href="https://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet"> <script type="text/ng-template" id="group-template.html"> <h4 class="panel-title" style="color:#fa39c3"> <span ng-class="{'text-muted': isDisabled}">{{heading}}</span> </h4> <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> {{item}} </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}"> </uib-accordion-heading> This is just some content to illustrate fancy headings. </uib-accordion-group> </uib-accordion> |