Angular.js множество директиви за атрибути, работещи независимо

Имам директива, която използвам като атрибут. Директивата добавя и премахва клас, което задейства css анимация, за да избледнее div навътре и навън. Имам това на няколко места на моята страница; обаче, след като първият div вземе стойността, останалите div (които не се виждат) също вземат стойността. Как да накарам тези директиви да работят независимо?

Директива:

.directive("scroll", function ($window) {
return function (scope, element, attrs) {

    function getScrollOffsets(w) {

        // Use the specified window or the current window if no argument 
        w = w || window;

        // This works for all browsers except IE versions 8 and before
        if (w.pageXOffset != null) return {
            x: w.pageXOffset,
            y: w.pageYOffset
        };

    }

    angular.element($window).bind("scroll", function (e) {
        var offset = getScrollOffsets($window);
         if (offset.y >= 10) {
             e.preventDefault();
             e.stopPropagation();
             element.removeClass('not-in-view');
             element.addClass('in-view');
         } else {
             e.preventDefault();
             e.stopPropagation();
             element.removeClass('in-view');
             element.addClass('not-in-view');
         }
        scope.$apply();
    });
};
});

HTML:

<div class="sidebar col-md-4" scroll>
   <h1>Content</h1>
</div>

<div class="sidebar col-md-4" scroll>
   <h1>More Content</h1>
</div>

person byrdr    schedule 01.06.2015    source източник
comment
Ще помогне ли проверката дали елементът е видим преди извършване на логиката на превъртане?   -  person sirrocco    schedule 01.06.2015
comment
моля, настройте плункер   -  person tpie    schedule 01.06.2015


Отговори (2)


Трябва да проверите дали елементът се вижда в прозореца за изглед от

function isElementInViewport (el) {

//special bonus for those using jQuery
if (typeof jQuery === "function" && el instanceof jQuery) {
    el = el[0];
}

var rect = el.getBoundingClientRect();

return (
    rect.top >= 0 &&
    rect.left >= 0 &&
    rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /*or $(window).height() */
    rect.right <= (window.innerWidth || document.documentElement.clientWidth) /*or $(window).width() */
);
}

като Как за да разберете дали DOM елемент е видим в текущия прозорец за изглед?

така че

angular.element($window).bind("scroll", function (e) {

     if (isElementInViewport(element)) {
         e.preventDefault();
         e.stopPropagation();
         element.removeClass('not-in-view');
         element.addClass('in-view');
     } else {
         e.preventDefault();
         e.stopPropagation();
         element.removeClass('in-view');
         element.addClass('not-in-view');
     }
    scope.$apply();
});
person kwangsa    schedule 01.06.2015
comment
Благодаря ти! Логиката ми беше неправилна, като задействах елементите въз основа на прозореца, а не на елемента. Също така изолирах обхвата и го накарах да работи. - person byrdr; 01.06.2015

Ето моето окончателно решение благодарение на @kwan, промених го малко.

.directive("scroll", function ($window) {
return{
scope:true,
link: function (scope, el, attrs) {
    function isElementInViewport (el) {

      //special bonus for those using jQuery
      if (typeof jQuery === "function" && el instanceof jQuery) {
          el = el[0];
      }
      var height = $(el).height();
      var rect = el.getBoundingClientRect();

      return (
          rect.top >= -(height / 1.25) &&
          rect.left >= 0 &&
          rect.bottom <= (window.innerHeight || document.documentElement.clientHeight)+ (height / 1.25) && /*or $(window).height() */
          rect.right <= (window.innerWidth || document.documentElement.clientWidth) /*or $(window).width() */
      );
      }

    angular.element($window).bind("scroll", function (e) {

       if (isElementInViewport(el)) {
           e.preventDefault();
           e.stopPropagation();
           el.removeClass('not-in-view');
           el.addClass('in-view');
       } else {
           e.preventDefault();
           e.stopPropagation();
           el.removeClass('in-view');
           el.addClass('not-in-view');
       }
      scope.$apply();
  });
      }
};
})
person byrdr    schedule 01.06.2015