使用AngularJS制作动态高度动画

pkbketx9  于 2022-10-31  发布在  Angular
关注(0)|答案(5)|浏览(247)

所以,我一直试图制作一种像Angular accordion 一样的动画,但没有成功。我用固定的高度来解决这个问题,但不是动态的。height: auto;不起作用。:(
也许你们中的一些人有过类似的问题?
我的代码:
HTML格式:

<head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular-route.js"></script>
    <link rel="stylesheet" href="style.css">
    <script src="script.js"></script>
  </head>

  <body>
    <section ng-app="myApp">
    <div ng-controller="myCtrl as vm">
        <ul ng-init="vm.tab=1">
            <li ng-repeat="item in vm.data">
              <a href ng-click="vm.tab = item.thingy">{{item.name}}</a>
              <div ng-show="vm.tab === item.thingy">
                <img ng-src="{{item.img}}" width="50px"><br>
                <div class="longDiv">{{item.description}}</div>
              </div>
            </li>
        </ul>
    </div>
  </section>
</body>
</html>

js:

var app = angular.module('myApp', []);

app.controller('myCtrl', ['$scope',
  function($scope) {
    var vm = this;

    vm.data = [{
      name: "First",
      title: "oneTitle",
      description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit ipsum dolor sit amet, consectetur ipsum dolor sit amet, consectetur.",
      year: "2013",
      img: "http://static.hdw.eweb4.com/media/wp_400/1/5/42735.jpg",
      thingy: 1
    }, {
      name: "third",
      title: "twoTitle",
      description: "Quisque pulvinar libero sed eros ornare",
      year: "2014",
      img: "http://static.hdw.eweb4.com/media/wp_400/1/1/8519.jpg",
      thingy: 2
    }, {
      name: "Second",
      title: "threeTitle",
      description: "Cras accumsan ipsum dolor sit amet, consectetur ipsum dolor sit amet, consectetur ipsum dolor sit amet, consectetur massa vitae tortor vehicula .",
      year: "2015",
      img: "http://static.hdw.eweb4.com/media/wp_400/1/5/43326.jpg",
      thingy: 3
    }, {
      name: "fourth",
      title: "FourTitle",
      description: "Suspendisse ipsum dolor sit amet, consectetur ipsum dolor sit amet, consectetur ipsum dolor sit amet, consectetur ipsum dolor sit amet, consectetur ipsum dolor sit amet, consectetur ipsum dolor sit amet, consectetur ipsum dolor sit amet, consectetur ipsum dolor sit amet, consectetur vitae mattis magna.",
      year: "2011",
      img: "http://static.hdw.eweb4.com/media/wp_400/1/5/42413.jpg",
  thingy: 4
    }];

  }
]);

提前感谢!Plnkr here

2ledvvac

2ledvvac1#

我已经通过创建“collapse”指令解决了这个问题:

ngModule.directive('collapse', [function () {
    return {
        restrict: 'A',

        link: function ($scope, ngElement, attributes) {
            var element = ngElement[0];

            $scope.$watch(attributes.collapse, function (collapse) {
                var newHeight = collapse ? 0 : getElementAutoHeight();

                element.style.height = newHeight +"px";
                ngElement.toggleClass('collapsed', collapse);
            });

            function getElementAutoHeight() {
                var currentHeight = getElementCurrentHeight();

                element.style.height = 'auto';
                var autoHeight = getElementCurrentHeight();

                element.style.height = currentHeight +"px";
                getElementCurrentHeight(); // Force the browser to recalc height after moving it back to normal

                return autoHeight;
            }

            function getElementCurrentHeight() {
                return element.offsetHeight
            }
        }
    };
}]);

要使用该指令,只需将其置于元素上,并将其设置为表示是否折叠该元素的作用域变量:

<div collapse="isCollapsed">
    This will be collapsed
</div>

现在你只需要在高度上应用一个CSS过渡,它就会平滑地折叠和展开。因为这个指令也添加了一个类,你可以应用其他的过渡,比如不透明度。
下面是一个Codepen示例:http://codepen.io/KaidenR/pen/GoRJLx

efzxgjgh

efzxgjgh2#

修改后的@kaiden回答,如果使用Angular 指令可以使用

require('./').directive('collapse', collapseDirective);

/**

* @ngInject
* /

function collapseDirective() {

   return {
    restrict: 'A',
    link: link
   };

   function link($scope, ngElement, attributes) {
     var element = ngElement[0];

     // set the height as a data attr so we can use it again later
     element.dataset.heightOld = angular.element(element).prop('offsetHeight');

     $scope.$watch(attributes.collapse, function (collapse) {
       var newHeight = !collapse ? 0 : element.dataset.heightOld;
       element.style.height = newHeight + 'px';
       ngElement.toggleClass('collapsed', collapse);
     }); 
   }
 }

作为链接函数,只需为高度添加CSS过渡。这将设置一个数据属性来存储高度,然后在切换时使用它。在我的应用程序中,我使用了一些标记,如

<ion-item class="item-accordion" collapse="vm.isActive($index)">

注意,这是在ng-repeat中,并调用视图模型上的函数。这也是一个离子项目,因此有了离子项目标签。

5jvtdoz2

5jvtdoz23#

您可以尝试将max-height设置为0,然后按照下面的建议删除样式/类:
http://css3.bradshawenterprises.com/animating_height/

atmip9wb

atmip9wb4#

因此,经过长时间的努力,我找到了一种简单但混乱的方法,它是制作jQuery accordion 的最简单、最快捷的方法。
基本上,我在我的$scope- accordion中创建了一个新变量,并在其中放入所有accordion html:

vm.data = [{
  name     : "First",
  accordion: ["<h3>Title1</h3><div>Content 1</div><h3>Title2</h3><div>Content 1</div>"]};

对我来说,这是可行的,因为现在我可以在ng-repeat中使用这个变量:

<div ng-repeat="item in vm.data>
    <div ng-repeat="acc in item.accordion" ng-bind-html="acc | normalHtml"></div>

只要这个变量中只有一个字符串,我就得到一个accordion div。然后,我在setTimout函数中调用accordion函数,一切都正常。
但这是混乱的,有点“用锤子,我可以用羽毛”的情况。
所以,目前这对我来说还可以,但我仍然在寻找一个更漂亮的解决方案。
谢谢你们所有人帮助我。如果你们中的一些人有任何想法如何使这件事变得更好,我欢迎每一个答案:)

mqkwyuun

mqkwyuun5#

好的,我想我找到了圣杯。至少对我来说是这样的:)
我在使用@Kaiden和@Gareth Fuller的解决方案时遇到了一些麻烦,因为任何外部折叠元素都将保持其在任何内部折叠元素折叠之前的原始高度。所以我从@Icycool的建议中得到了启发,将其改为在最大高度上动画,并将高度设置为“自动”,这就解决了这个问题。
您可以运行下面的工作演示。
第一个

相关问题