javascript - 如何为导致更改的点击事件相关的 ng-repeat 元素设置动画

标签 javascript jquery css angularjs jquery-ui

我正在尝试制作用户从不同元素集中选择元素的动画。 该元素应该从点击的集合动画到它在所选元素列表中的新位置。

在下面的演示中,将粉色框视为可用元素,将带边框的框视为所选元素的列表(蓝色框)。用户可以通过单击任一粉红色框来选择元素:

angular.module('test', ['ngAnimate'])
  .controller('testCtrl', function($scope) {
    $scope.products = [{}, {}, {}, {}];
    $scope.purchased = [{}];
    $scope.purchase = function(dir) {
      $scope.direction = dir
      $scope.purchased.push($scope.products.pop());
    };
  })
  .directive('testDir', function($animate) {
    return {
      link: function(scope, element) {
        $animate.on('enter', element, function(element, phase) {
          $target = scope.direction == 'left' ? $('.stock:first') : $('.stock:last');
          element.position({
            my: 'center',
            at: 'center',
            of: $target,
            using: function(pos, data) {
              $(this).css(pos);
              $(this).animate({
                top: 0,
                left: 0
              });
            }
          });
        });
      }
    };
  });
.stock {
  display: inline-block;
  width: 50px;
  height: 50px;
  background: hotpink;
}
.stock.right {
  margin-left: 100px;
}
.product {
  height: 50px;
  width: 50px;
  border: 1px solid;
}
.purchased {
  height: 60px;
  margin-top: 100px;
  border: 2px dotted;
}
.purchased .product {
  display: inline-block;
  margin: 5px;
  background: dodgerblue;
}
<script src="https://code.jquery.com/jquery-2.1.3.min.js"></script>
<script src="https://code.jquery.com/ui/1.11.2/jquery-ui.js"></script>
<script src="https://code.angularjs.org/1.4.8/angular.js"></script>
<script src="https://code.angularjs.org/1.4.8/angular-animate.js"></script>
<div ng-app="test" ng-controller="testCtrl">
  <div class="stock" ng-click="purchase('left')"></div>
  <div class="stock right" ng-click="purchase('right')"></div>
  <div class="purchased clearfix">
    <div class="product" ng-repeat="product in purchased" data-test-dir>
    </div>
  </div>
</div>


嗯,它有点管用 - 但我正在使用 jQuery-ui 找出起始位置(粉红色框的位置在响应式设计中会很谨慎)和 jquery animate 方法来为元素设置动画。

此外,我还必须将点击的方向存储在范围内,并且我在 enter 事件监听器中设置了初始位置和结束位置的动画。

我一直在阅读和试验很多内置的 Angular 动画 Hook ,但无法找到从相对/动态位置为元素设置动画的正确方法。

是否有更好的方法以 angular js 方式实现相同的用户体验..?

最佳答案

如果我没有正确理解您的问题(如果没有,请告诉我);我认为解决问题的一种方法是这样的:

同时假设您的产品的尺寸(宽度)是恒定的 - 设置为 50px 或其他东西 - ;您可以将粉红色元素的位置设置为绝对;然后对粉红色元素使用 ng-repeat,在 html 中使用一个简短的 ng-style 属性,如下所示:

<div ng-repeat="item in products" ng-style="{'left': $index*50 + 'px'}" ng-click="add-to-purchased($index)"></div>

关于已购买的产品:在将产品推送到“已购买”数组后,您可以简单地为产品设置动画,而不是在“已购买”数组上使用 ng-repeat,而是在“添加到已购买”功能中“顶部:'到边框元素的高度距离'”和“左侧”等于 {$scope.purchased.length*50 + 'px'}。然后使用 ng-class(带有切换)添加一个类用于着色和其他 css 东西......(你也可以考虑颜色变化的过渡。你可能知道)

我还认为您可以使用 ng-class 处理不同的高度和顶部问题(以防产品数量超过一条线的容量),该 ng-class 添加具有新“顶部”值的类基于:($index > some-number),还有另一个 ng-class 用于上层元素(位于边框元素顶部的元素),改变它的高度 ...

希望对你有帮助


更新:

不幸的是我没有很好地理解这个问题。但是现在看问题,我认为有一种方法可以更动态地做到这一点。

$scope.purchase 函数中,您可以使用 $broadcast 向您的指令发送消息,并像这样传递点击的元素(对于库存中的任何元素,它是创建的是否使用 ng-repeat):

<div class="stock" ng-click="purchase($event)"></div>

和:

$scope.purchase = function(event) {
  $scope.purchased.push($scope.products.pop());
  $scope.$broadcast('purchaseHappened', event.target);
};

在你的指令中,放置事件监听器:

scope.$on('purchaseHappened', function(event, target) {
     //catch target in here, and then use it's position to animate the new elements...
})

我认为您还可以使用 target.getBoundingClientRect() 获取元素相对于视口(viewport)的位置(.top , .left ,...) 而不是 jquery-ui 的 .position 如果你想...

是否更接近解决方案?

关于javascript - 如何为导致更改的点击事件相关的 ng-repeat 元素设置动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34875771/

相关文章:

html - 如何让div展开宽度100%

jquery - Visual Studio html/css 更改问题

javascript - Ag 网格阻止访问 React 状态变量的当前值

javascript - 替换字符串中的多个子字符串 - Javascript

javascript - jquery Monthpicker如何设置默认月份和年份

javascript - 如何在打开下拉菜单时隐藏当前选定的选项

javascript - 刷新页面时 hasClass 不起作用

jquery - 如何使用 Gmaps.js 在标记点击时创建自定义弹出窗口?

javascript - 响应式顶部栏不展开

javascript - 使用 JavaScript 检测特定的 CSS3 关键帧