6

我正在构建一个小型应用程序,并且正在使用 AngularJS。在应用程序内部,我需要一个可折叠元素,使用 Twitter Bootstrap 就像在我的目标元素和触发器上添加库和一些标签一样简单。

但我试图不加载其他外部库,如 bootstrap 或任何其他库,所以我试图用 Angular 实现相同的行为:

$scope.collapse = function(target) {

        var that = angular.element(document).find(target),

            transitioned = {
                'WebkitTransition' : 'webkitTransitionEnd',
                'MozTransition'    : 'transitionend',
                'OTransition'      : 'oTransitionEnd otransitionend',
                'msTransition'     : 'MSTransitionEnd',
                'transition'       : 'transitionend'
            },

            _transitioned = transitioned[ Modernizr.prefixed('transition') ],

            height = that.outerHeight(true);

        if (angular.element(that).hasClass("in")) {
            that.height(0);
        } else {
            that.height(height);
        };

        that.on(_transitioned, function() {
            that.toggleClass("in");
        });
    };

如您所见,我正在尝试转换高度(因为元素在高度上有转换),最后只添加类in。但这不是很好,因为如果我在过渡端收听,它将在该元素内的任何过渡端触发。

我需要一些帮助,如何仅使用 angular 重写引导可折叠?我不需要 bootstrap 所具有的事件shownhidden或者showhide我只需要通过转换触发元素的简单折叠并保持我的元素高度动态(我不想要固定高度,否则我只会使用CSS 实现折叠)。我只需要确定正确的方向:)

4

3 回答 3

7

好像你只想用 CSS3 过渡折叠一些东西?

好吧,你可以这样做,但控制器是错误的地方这样做。您应该使用指令或自定义指令来执行此操作。幸运的是,您可以使用 Angular 原生指令(例如 ng-class)来做到这一点。

HTML:

<button ng-click="open = !open">Toggle</button>    
<div ng-class="{ showMe: open }" class="collapsable">
  <h3>This should collapse</h3>
</div>

最重要的是,你的 CSS:

  .collapsable {
    display: inline-block;
    overflow: hidden;
    height: 0;
    transition: height 1s;
    -webkit-transition: height 1s;        
    -moz-transition: height 1s;        
    -o-transition: height 1s;         
  }
  .collapsable.showMe {
    height: 100px;
  }

这是它的工作原理。

需要注意的是,CSS3 过渡不适用于所有浏览器。特别是在 IE 中。最后,我认为您最好使用其他人已经制作的插件,然后在监视一些布尔值的自定义指令中利用它。

我希望这会有所帮助。


编辑

height: auto不适用于 CSS 过渡(至少截至本文发表时)。所以,这就是为什么你真的想使用别人的插件,而不是重新发明轮子。即使它只是 JQuery 的 animate() 方法。滚动您自己的指令的伪代码将是这样的:(假设您使用的是 JQuery)

app.directive('collapseWhen', function () {
   return function(scope, elem, attr) {
     scope.$watch(attr.collapseWhen, function(val) {
        var clone = elem.clone().appendTo('body');
        var h = clone.height();
        clone.remove();
        scope.animate({ height: (val ? h : 0) + 'px' }, 1000);
     }
   }
});

然后你会像这样使用它:

<button ng-click="foo = !foo">Toggle</button>
<div collapse-when="foo">

同样,上面是伪代码,我不知道它是否会起作用,这只是给你一个想法,如果你真的想自己动手的话。

于 2013-02-15T15:57:04.910 回答
2

如果我理解这些问题,我的解决方案是使用 angular $animateCss。这里有文档和示例https://docs.angularjs.org/api/ngAnimate/service/ $animateCss

使用 $animateCss 服务,您可以使用 ngAnimate 创建自己的动画。这是一个角度模块的例子。演示在下面的链接中

var AppModule = angular.module('myApp', ['ngAnimate'])
  .controller('collapseCtrl', ['$scope', function($scope) {
    $scope.btn1 = $scope.btn2 = $scope.btn3 = false;
  }]).animation('.my-collapse', ['$animateCss', function($animateCss) {
    return {
      enter: function(element, doneFn) {
        var height = element[0].offsetHeight;
        return $animateCss(element, {
          from: {
            height: '0px',
            overflow: 'hidden'
          },
          to: {
            height: height + 'px'
          },
          cleanupStyles: true,
          duration: 0.3 // one second
        });
      },
      leave: function(element, doneFn) {
        var height = element[0].offsetHeight;
        return $animateCss(element, {
          to: {
            height: '0px',
            overflow: 'hidden'
          },
          from: {
            height: height + 'px'
          },
          cleanupStyles: true,
          duration: 0.3 // one second
        });
      }
    };
  }]);

https://plnkr.co/edit/DjU1A2vmiBB1dYXjkiN1

于 2016-05-31T13:45:25.740 回答
1

Roland,看看angular-ui 团队的Bootstrap 项目

于 2013-02-15T18:35:03.297 回答