web-dev-qa-db-fra.com

Angularjs: Comment déclencher un événement lorsque le défilement atteint le bas de la barre de défilement dans div?

J'essaie de déclencher un événement lorsque la barre de défilement atteint la fin. J'ai trouvé ceci cet exemple . Voici mon code. Le problème est qu'il n'appelle pas loadmore () du tout ... Les valeurs des instructions de la console sont:

848
899
in scroll
881
899
in scroll
892
899
in scroll
897
899
in scroll
900
899

Il semble que cela ne se passe jamais comme ça! Ce qui est étrange, c'est que si je le débogue dans l'élément inspect, l'événement est déclenché. ..... ma directive:

directive('scrolly', function () {
    return {
        restrict: 'A',
        link: function (scope, element, attrs) {
            var raw = element[0];
            console.log('loading directive');
            element.bind('scroll', function () {
                console.log('in scroll');
                console.log(raw.scrollTop + raw.offsetHeight);
                console.log(raw.scrollHeight);
                if (raw.scrollTop + raw.offsetHeight == raw.scrollHeight) { //at the bottom
                    scope.$apply(attrs.scrolly);
                }
            })
        }
    }
23
Sara

Au lieu de vérifier l’égalité, veuillez vérifier si le côté gauche est supérieur au côté droit dans l’instruction if car c’est le cas pour la barre de défilement en bas.

raw.scrollTop + raw.offsetHeight > raw.scrollHeight

Voici le travail jsfiddle .

29
Rathish Cholarajan

Vous m'avez donné quelques bons conseils ... Voici un exemple de travail complet pour ceux qui découvrent ce post:

JS:

app.controller("controller", function ($scope) {
    $scope.test = function () {
        alert("hello!");
    }
}

HTML:

<div class="br-section1" on-scroll-to-bottom="test()">
</div>

Directive sur les applications:

app.directive('onScrollToBottom', function ($document) {
    //This function will fire an event when the container/document is scrolled to the bottom of the page
    return {
        restrict: 'A',
        link: function (scope, element, attrs) {

            var doc = angular.element($document)[0].body;

            $document.bind("scroll", function () {

                //console.log('in scroll');
                //console.log("scrollTop + offsetHeight:" + (doc.scrollTop + doc.offsetHeight));
                //console.log("scrollHeight: " + doc.scrollHeight);

                if (doc.scrollTop + doc.offsetHeight >= doc.scrollHeight) {
                    //run the event that was passed through
                    scope.$apply(attrs.onScrollToBottom);
                }
            });
        }
    };
});
8
Mark G

Je cherchais un bout de code pour m'aider à faire cela, mais je ne trouvais rien qui en valait la peine, alors j'ai trouvé cette directive assez facile à utiliser pour le faire.

'use strict';
// Tested with Angular 1.3, 1.4.8
angular.module('scrollToEnd', [])
  /**
   * @ngdoc directive
   * @name scrollToEnd:scrollToEnd
   * @scope
   * @restrict A
   *
   * @description
   * Supply a handler to be called when this element is scrolled all the way to any extreme.
   * The callback must have the following signature:
   * void function (direction:'top'|'bottom'|'left'|'right')
   * If the `bindToWindow` attribute is truthy, the callback will be issued for the window
   * instead of the element that the directive is on.
   *
   * Example usage:
   * `<div scroll-to-end="scrollToEndWindow" bind-to-window="true">`
   * This will call the controller's `scrollToEndWindow` function whenever the window reaches
   * the edges when scrolling. If the div itself is a scrollable element for which the
   * handler should be called instead, remove the bind-to-window attribute entirely.
   *
   * @param {function}  emScrollToEnd   Callback to be invoked
   * @param {boolean}       bindToWindow        Bind to the window instead of the element
   *
   */
  .directive('scrollToEnd', function ($window) {
    // Get the specified element's computed style (height, padding, etc.) in integer form
    function getStyleInt(elem, prop) {
      try {
        return parseInt(window.getComputedStyle(elem, null).getPropertyValue(prop), 10);
      } catch (e) {
        return parseInt(elem.currentStyle[prop], 10);
      }
    }

    // Get the 'innerHeight' equivalent for a non-window element, including padding
    function getElementDimension(elem, prop) {
      switch (prop) {
        case 'width':
          return getStyleInt(elem, 'width') +
          getStyleInt(elem, 'padding-left') +
          getStyleInt(elem, 'padding-right');
        case 'height':
          return getStyleInt(elem, 'height') +
          getStyleInt(elem, 'padding-top') +
          getStyleInt(elem, 'padding-bottom');
        /*default:
          return null;*/
      }
    }
    return {
      restrict: 'A',
      scope: {
        callback: '=scrollToEnd'
      },
      link: function (scope, elem, attr) {
        var callback = scope.callback || function () {};
        var boundToWindow = attr.bindToWindow;
        var body = document.body;
        var html = document.documentElement;
        var boundElement = boundToWindow ? angular.element($window) : elem;
        var oldScrollX = 0;
        var oldScrollY = 0;
        var handleScroll = function () {
          // Dimensions of the content, including everything scrollable
          var contentWidth;
          var contentHeight;
          // The dimensions of the container with the scrolling, only the visible part
          var viewportWidth;
          var viewportHeight;
          // The offset of how much the user has scrolled
          var scrollX;
          var scrollY;

          if (boundToWindow) {
            // Window binding case - Populate Dimensions
            contentWidth = Math.max(
              body.scrollWidth,
              body.offsetWidth,
              html.clientWidth,
              html.scrollWidth,
              html.offsetWidth
            );
            contentHeight = Math.max(
              body.scrollHeight,
              body.offsetHeight,
              html.clientHeight,
              html.scrollHeight,
              html.offsetHeight
            );
            viewportWidth = window.innerWidth;
            viewportHeight = window.innerHeight;
            scrollX = (window.pageXOffset || html.scrollLeft) - (html.clientLeft || 0);
            scrollY = (window.pageYOffset || html.scrollTop) - (html.clientTop || 0);
          } else {
            // DOM element case - Populate Dimensions
            var domElement = boundElement[0];
            contentWidth = domElement.scrollWidth;
            contentHeight = domElement.scrollHeight;
            viewportWidth = getElementDimension(domElement, 'width');
            viewportHeight = getElementDimension(domElement, 'height');
            scrollX = domElement.scrollLeft;
            scrollY = domElement.scrollTop;
          }

          var scrollWasInXDirection = oldScrollX !== scrollX;
          var scrollWasInYDirection = oldScrollY !== scrollY;
          oldScrollX = scrollX;
          oldScrollY = scrollY;

          if (scrollWasInYDirection && scrollY === 0) {
            callback('top');
          } else if (scrollWasInYDirection && scrollY === contentHeight - viewportHeight) {
            callback('bottom');
          } else if (scrollWasInXDirection && scrollX === 0) {
            callback('left');
          } else if (scrollWasInXDirection && scrollX === contentWidth - viewportWidth) {
            callback('right');
          }
        };
        boundElement.bind('scroll', handleScroll);
        // Unbind the event when scope is destroyed
        scope.$on('$destroy', function () {
          boundElement.unbind('scroll', handleScroll);
        });
      }
    };
  });

https://Gist.github.com/podrezo/f80f35d6d0655f4d550cac4747c110ff

Voici un jsfiddle pour l'essayer:

https://jsfiddle.net/va4x5r26/2/

Fonctionne avec Angular 1.3 et 1.4.8 et testé sur IE10 et Chrome 55.

4
Petro Podrezo

Lorsque la barre de défilement du navigateur atteint le bas, nous devons déclencher un événement. Le code ci-dessous fonctionnera pour Angular 6.

 import { HostListener } from '@angular/core';
     @HostListener('window:scroll', ['$event'])
      onScroll(): void {
        if ((window.innerHeight + window.scrollY) >= (document.documentElement.scrollHeight - 1)) {
          // Place your code here
        }
      }
0
Indradeep