improve scrolling performance by registering events only once instead of once per entry

This commit is contained in:
Athou
2013-09-10 15:56:30 +02:00
parent dd94125d52
commit bb4529b6f1
4 changed files with 77 additions and 104 deletions

View File

@@ -59,96 +59,6 @@ module.directive('ngBlur', function() {
};
});
/**
* Fired when the top of the element is not visible anymore
*/
module.directive('onScrollMiddle', function() {
return {
restrict : 'A',
link : function(scope, element, attrs) {
var w = $(window);
var e = $(element);
var d = $(document);
var offset = parseInt(attrs.onScrollMiddleOffset, 10);
var down = function() {
var docTop = w.scrollTop();
var elemTop = e.offset().top;
var threshold = docTop === 0 ? elemTop - 1 : docTop + offset;
return (elemTop > threshold) ? 'below' : 'above';
};
var up = function() {
var docTop = w.scrollTop();
var elemTop = e.offset().top;
var elemBottom = elemTop + e.height();
var threshold = docTop === 0 ? elemBottom - 1 : docTop + offset;
return (elemBottom > threshold) ? 'below' : 'above';
};
if (!w.data.scrollInit) {
w.data.scrollPosition = d.scrollTop();
w.data.scrollDirection = 'down';
var onScroll = function(e) {
var scroll = d.scrollTop();
w.data.scrollDirection = (scroll - w.data.scrollPosition > 0) ? 'down' : 'up';
w.data.scrollPosition = scroll;
scope.$apply();
};
w.bind('scroll', _.throttle(onScroll, 500));
w.data.scrollInit = true;
}
scope.$watch(down, function downCallback(value, oldValue) {
if (value != oldValue && value == 'above')
scope.$eval(attrs.onScrollMiddle);
});
scope.$watch(up, function upCallback(value, oldValue) {
if (value != oldValue && value == 'below')
scope.$eval(attrs.onScrollMiddle);
});
}
};
});
/**
* Scrolls to the element if the value is true and the attribute is not fully
* visible, unless the attribute scroll-to-force is true
*/
module.directive('scrollTo', ['$timeout', function($timeout) {
return {
restrict : 'A',
link : function(scope, element, attrs) {
scope.$watch(attrs.scrollTo, function(value) {
if (!value)
return;
var force = scope.$eval(attrs.scrollToForce);
// timeout here to execute after dom update
$timeout(function() {
var docTop = $(window).scrollTop();
var docBottom = docTop + $(window).height();
var elemTop = $(element).offset().top;
var elemBottom = elemTop + $(element).height();
if (!force && (elemTop > docTop) && (elemBottom < docBottom)) {
// element is entirely visible
return;
} else {
var offset = parseInt(attrs.scrollToOffset, 10);
var scrollTop = $(element).offset().top + offset;
$('html, body').animate({
scrollTop : scrollTop
}, 0);
}
});
});
}
};
}]);
/**
* Prevent mousewheel scrolling from propagating to the parent when scrollbar
* reaches top or bottom