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

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

问题描述

当一个面板打开时,我需要让它滚动回刚刚点击的面板的.panel-title".我知道我可以创建一个指令来执行此操作,例如(从 本网站):

.directive( 'scrollTop', scrollTop );函数滚动顶部(){返回 {限制:'A',链接:链接};}函数链接($scope,元素){$scope.collapsing = false;$scope.$watch(函数(){返回 $(element).find('.panel-collapse').hasClass('collapsing');}, 函数(状态){如果( $scope.collapsing && !status ){if ( $(element).hasClass( 'panel-open' ) ) {$( 'html,body' ).animate({scrollTop: $(element).offset().top - 20}, 500 );}}$scope.collapsing = 状态;});}

在我应该使用的 HTML 中:

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

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

我只需要它滚动回被点击的面板的.panel-title".我认为这是非常荒谬的,当很多时间面板内容可能会变得很长时,这似乎很难做到,而且我认为大多数人都希望在打开面板时滚动到信息的顶部.

我在这里看到了其他帖子,但他们似乎没有处理 AngularJS.我正在使用"ui-bootstrap-tpls-2.1.3 "

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

非常感谢任何帮助.

解决方案

这可能是一种快速而肮脏的方法,但效果很好

angular.module('ui.bootstrap.demo', ['ngAnimate', 'ui.bootstrap']).controller('AccordionDemoCtrl', function($scope) {$scope.oneAtATime = true;$scope.groups = [{title: '动态组头 - 1',内容:'动态组主体 - 1'}, {title: '动态组头 - 2',内容:'动态组正文 - 2 动态组头 - 2 动态组头 - 2 动态组头 - 2 动态组头 - 2 动态组头 - 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: 真,isFirstDisabled: 假};//滚动var 手风琴 = $('.accordion'), 超时;手风琴.on('click', '.panel-heading', function(e) {if(e.target.nodeName != 'SPAN') 返回;var 元素 = this;清除超时(超时);//因为我们不知道动态内容的确切 offsetTop//使用超时350,让angular完成它的渲染超时 = 设置超时(函数(){手风琴.动画({滚动顶部:element.offsetTop -2}, 300);}, 350);});});

.accordion {最大高度:220px;溢出:自动;填充:2px;8px 0 0;}*:focus { 大纲: 无 !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="样式表"><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>

<div class="panel-collapse collapse" uib-collapse="!isOpen"><div class="panel-body" style="text-align: right" ng-transclude></div>

<div class="accordion"><uib-accordion close-others="oneAtATime"><uib-accordion-group Heading="Static Header, 初始展开" 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-accordion组的主体生长以适应内容</p><button type="button" class="btn btn-default btn-sm" ng-click="addItem()">添加项目</button><div ng-repeat="item in items">{{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-手风琴>

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天全站免登陆