简体   繁体   English

Angularjs:当滚动到达div中滚动条的底部时如何触发事件?

[英]Angularjs: How to trigger event when scroll reaches to the bottom of the scroll bar in div?

I'm trying to trigger an event when scroll bar reaches the end.我试图在滚动条到达末尾时触发一个事件。 I found this this example .我发现这个这个例子 Here is my code.这是我的代码。 The problem is that it doesn't call loadmore() at all.问题是它根本不调用 loadmore() 。 The values of the console statments are:控制台语句的值是:

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

It seems that it never goes to that if statement!似乎它永远不会去那个 if 语句! The weird part is that if I debug it in inspect element then it triggers the event.奇怪的是,如果我在检查元素中调试它,那么它会触发事件。 ..... my 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);
                }
            })
        }
    }

Instead of checking for equality, please check if the left side is greater than the right side in the if statement since that's the case for the scrollbar to be at the bottom.请检查 if 语句中的左侧是否大于右侧,而不是检查是否相等,因为滚动条位于底部就是这种情况。

raw.scrollTop + raw.offsetHeight > raw.scrollHeight

Here is the working jsfiddle .这是工作的jsfiddle

You gave me a few good tips ... heres a complete working example for anyone else who stumbles across this post:你给了我一些很好的提示......这是一个完整的工作示例,供其他偶然发现这篇文章的人使用:

JS: JS:

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

HTML: HTML:

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

App Directive:应用指令:

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);
                }
            });
        }
    };
});

I was looking for a snippet to help me do this, but couldn't find anything worthwhile so I came up with this fairly easy to use directive to do this我正在寻找一个片段来帮助我做到这一点,但找不到任何有价值的东西,所以我想出了这个相当容易使用的指令来做到这一点

'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 https://gist.github.com/podrezo/f80f35d6d0655f4d550cac4747c110ff

Here's a jsfiddle to try it out:这是一个 jsfiddle 来尝试一下:

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

Works with Angular 1.3 and 1.4.8, and tested on IE10 and Chrome 55.适用于 Angular 1.3 和 1.4.8,并在 IE10 和 Chrome 55 上测试。

I took the Mark's code and I made some changes to add support on div elements.我采用了 Mark 的代码,并进行了一些更改以添加对div元素的支持。 Note that you can define another attribute to configure the threshold (50 in my case).请注意,您可以定义另一个属性来配置阈值(在我的情况下为 50)。

angular.module('O2DigitalSite').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 ele = element[0];
            element.bind("scroll", function () {
                //console.log((ele.scrollTop + ele.offsetHeight) + " / " + (ele.scrollHeight));
                if (ele.scrollTop + ele.offsetHeight >= ele.scrollHeight - 50) {
                    //run the event that was passed through
                    scope.$apply(attrs.onScrollToBottom);
                }
            });
        }
    };
});

When browser's scroll bar reached to down, we need to fire an event.当浏览器的滚动条向下时,我们需要触发一个事件。 Below code will work for Angular 6.下面的代码适用于 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
        }
      }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM