AngularJS/ui-bootstrap手风琴-单击时滚动到活动(打开)手风琴的顶部 [英] AngularJS / ui-bootstrap accordion - scroll to top of active (open) accordion on click

查看:88
本文介绍了AngularJS/ui-bootstrap手风琴-单击时滚动到活动(打开)手风琴的顶部的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

打开一个面板时,我需要将其滚动回到刚刚单击的面板的".panel-title".我知道我可以创建一个指令来做到这一点,例如(从

在HTML中,我应该使用:

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

但这似乎不起作用.当您单击第二个面板时,它会打开第一个和第二个面板,打开第三个面板时甚至不会滚动到顶部.

我只需要它可以滚动回到所单击面板的".panel-title".我认为这很荒谬,因为很多时候面板内容会变得很长,而且似乎很多人都想在面板打开时滚动到信息的顶部./p>

我在这里看到过其他文章,但它们似乎与AngularJS无关.我正在使用"ui-bootstrap-tpls-2.1.3"

编辑-如果您愿意,这里有一个柱塞.

非常感谢您的帮助.

解决方案

这可能是一种快速而肮脏的方法,但可以正常使用

  angular.module('ui.bootstrap.demo',['ngAnimate','ui.bootstrap']).controller('AccordionDemoCtrl',function($ scope){$ scope.oneAtATime = true;$ scope.groups = [{标题:动态组标题-1",内容:动态组主体-1"},{标题:动态组标题-2",内容:动态组主体-2个动态组头-2个动态组头-2个动态组头-2个动态组头-2个动态组头-2"}];$ scope.items = ['项目1','项目2','项目3'];$ scope.addItem = function(){var newItemNo = $ scope.items.length +1;$ scope.items.push('Item'+ newItemNo);};$ scope.status = {isFirstOpen:是的,isFirstDisabled:否};//滚动var手风琴= $('.accordion'),timeOut;Accordion.on('click','.panel-heading',function(e){if(e.target.nodeName!='SPAN')返回;var element = this;clearTimeout(timeOut);//因为我们不知道动态内容的确切offsetTop//使用超时350,它使角度完成其渲染timeOut = setTimeout(function(){手风琴动画({scrollTop:element.offsetTop -2},300);},350);});});  

  .accordion {最大高度:220像素;溢出:自动;填充:2px;8px 0 0;}*:focus {大纲:无!重要;}  

 < 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">< spanng-class ="{'text-muted':isDisabled}"> {{heading}}</span></a></h4></div>< div class ="panel-collapsecollapse" 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 =最初已扩展的静态标题" is-open ="status.isFirstOpen" is-disabled ="status.isFirstDisabled">此内容直接在模板中.</uib-accordion-group>< uib-accordion-group heading ="{{group.title}}""ng-repeat =" group in groups>{{group.content}}</uib-accordion-group>< uib-accordion-group heading =动态主体内容">< p> uib手风琴组的主体成长为适合内容的</p>.< button type ="button" class ="btn btn-default btn-sm" ng-click ="addItem()">添加项</button>< div ng-repeat =项目中的项目"> {{item}}</div></uib-accordion-group>< uib-accordion-group heading =自定义模板" template-url ="group-template.html">你好</uib-accordion-group>< uib-accordion-group heading =删除帐户" panel-class ="panel-danger">< p>请删除您的帐户,点击下面的按钮</p>< p>请删除您的帐户,点击下面的按钮</p>< p>请删除您的帐户,点击下面的按钮</p>< button class ="btn btn-danger">删除</button></uib-accordion-group>< uib-accordion-group is-open ="status.open">< uib-accordion-heading>我也可以加价!< i class ="pull-right glyphicon" ng-class ="{'glyphicon-chevron-down':status.open,'glyphicon-chevron-right':!status.open}"</i></uib-accordion-heading>这只是一些说明标题的内容.</uib-accordion-group></uib-accordion></div></div></div>  

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.

解决方案

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>

这篇关于AngularJS/ui-bootstrap手风琴-单击时滚动到活动(打开)手风琴的顶部的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆