Angularjs: comment déclencher un événement quand scroll atteint le bas de la barre de défilement dans div?
j'essaie de déclencher un événement quand la barre de défilement atteint la fin. J'ai trouvé ce cet exemple. Voici mon code. Le problème est qu'il n'a pas appeler loadmore (). Les valeurs de la console relevés sont les suivants:
848
899
in scroll
881
899
in scroll
892
899
in scroll
897
899
in scroll
900
899
Il semble qu'il ne va jamais que si l'instruction! Ce qui est étrange, c'est que si je le débogage dans inspecter l'élément, puis il déclenche l'événement. ..... 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);
}
})
}
}
3 réponses
au lieu de vérifier pour l'égalité, s'il vous plaît vérifier si le côté gauche est plus grand que le côté droit dans la déclaration if puisque c'est le cas pour le scrollbar d'être au bas.
raw.scrollTop + raw.offsetHeight > raw.scrollHeight
voici le travail jsfiddle.
Vous m'avez donné quelques bons conseils ... heres un travail complet exemple pour quelqu'un d'autre qui tombe sur 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 App:
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);
}
});
}
};
});
je cherchais un extrait pour m'aider à le faire, mais je n'ai rien trouvé qui en vaille 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 les angulaires 1.3 et 1.4.8, et testé sur IE10 et Chrome 55.