$ window .on(" scroll")仅在最后一个指令中工作

时间:2016-01-16 22:12:40

标签: javascript jquery angularjs

我试图创建一个简单的指令,在元素附近滚动时设置或删除类。我在scroll上使用$window事件回调,但问题是它只能用于最后一个指令。

plunker

HTML

<html ng-app="myApp">

  <head>
    <link rel="stylesheet" href="style.css">
    <script src="//code.jquery.com/jquery-1.12.0.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
    <script src="script.js"></script>
  </head>

  <body>
    <div class="box hidden" on-scroll-class="{add: 'large', remove: 'hidden'}"></div>
    <div class="box hidden" on-scroll-class="{add: 'large', remove: 'hidden'}"></div>
    <div class="box hidden" on-scroll-class="{add: 'large', remove: 'hidden'}"></div>
  </body>

</html>

JS

var app = angular.module("myApp", []);
app.directive("onScrollClass", ["$window", function ($window) {
    return {
      restrict: "A",
      scope: {
        onScrollClass: "@",
        onScrollClassReverse: "@",
        onScrollOffset: "@"
      },
      link: function(scope, element, attrs) {
              var reverse = angular.isDefined(scope.onScrollClassReverse) ?
                scope.onScrollClassReverse : false;

              var offset = angular.isDefined(scope.onScrollOffset) ?
                scope.onScrollOffset : 150;

              var classToAddObj = scope.$eval(scope.onScrollClass);
              var classToAdd;
              var classToRemove = null;

              if (angular.isObject(classToAddObj)) {
                classToAdd = classToAddObj.add;
                classToRemove = classToAddObj.remove;
              } else {
                classToAdd = classToAddObj;
              }

              $element = $(element);
              $($window).on("scroll", function() {
                  console.log($element);
                  console.log($element.offset().top);
                  if (this.pageYOffset >= $element.offset().top - offset) {
                      $element.addClass(classToAdd);
                      $element.removeClass(classToRemove);

                  } else if (reverse) {
                      $element.addClass(classToRemove);
                      $element.removeClass(classToAdd);
                  }
                });

          }
      }
}]);

CSS

body {
  height: 2000px;
}

.hidden {
  opacity: .3;
}

.large {
  transform: scale(1.2);
}

.box {
  background-color: tomato;
  width: 200px;
  height: 200px;
  margin: 50px auto;
  transition: all .5s ease;

}

1 个答案:

答案 0 :(得分:1)

它与Angular无关。

您正在设置变量$element而不声明它是变量。 由于Javascript原型继承,它将尝试在原型链中找到该变量。 如果它找不到它,它会把它当作一个全局变量。

这就是为什么只有最后一条指令适合你,它每次都覆盖$element变量。

只需在var之前添加$element,并记住始终使用var关键字声明变量(或let(ES 2015)更好)。