Files
ionic-framework/js/ext/angular/src/service/delegates/ionicScrollDelegate.js
Andy Joslin c2bbd9e96e feat($ionicScrollDelegate): add .anchorScroll() function
Scrolls to the location of element with id matching $location.hash(). If
$location.hash() is blank or the id does not exist, it will scroll to
the top.
2014-02-09 11:37:30 -05:00

119 lines
3.7 KiB
JavaScript

(function() {
'use strict';
angular.module('ionic.ui.service.scrollDelegate', [])
.factory('$ionicScrollDelegate', ['$rootScope', '$timeout', '$q', '$anchorScroll', '$location', '$document', function($rootScope, $timeout, $q, $anchorScroll, $location, $document) {
return {
/**
* Trigger a scroll-to-top event on child scrollers.
*/
scrollTop: function(animate) {
$rootScope.$broadcast('scroll.scrollTop', animate);
},
scrollBottom: function(animate) {
$rootScope.$broadcast('scroll.scrollBottom', animate);
},
resize: function() {
$rootScope.$broadcast('scroll.resize');
},
anchorScroll: function() {
$rootScope.$broadcast('scroll.anchorScroll');
},
tapScrollToTop: function(element) {
var _this = this;
ionic.on('tap', function(e) {
var el = element[0];
var bounds = el.getBoundingClientRect();
if(ionic.DomUtil.rectContains(e.gesture.touches[0].pageX, e.gesture.touches[0].pageY, bounds.left, bounds.top, bounds.left + bounds.width, bounds.top + 20)) {
_this.scrollTop();
}
}, element[0]);
},
finishRefreshing: function($scope) {
$scope.$broadcast('scroll.refreshComplete');
},
/**
* Attempt to get the current scroll view in scope (if any)
*
* Note: will not work in an isolated scope context.
*/
getScrollView: function($scope) {
return $scope.scrollView;
},
/**
* Register a scope for scroll event handling.
* $scope {Scope} the scope to register and listen for events
*/
register: function($scope, $element) {
//Get scroll controller from parent
var scrollCtrl = $element.controller('$ionicScroll');
if (!scrollCtrl) {
return;
}
var scrollView = scrollCtrl.scrollView;
var scrollEl = scrollCtrl.element;
function scrollViewResize() {
// Run the resize after this digest
return $timeout(function() {
scrollView.resize();
});
}
$element.bind('scroll', function(e) {
$scope.onScroll && $scope.onScroll({
event: e,
scrollTop: e.detail ? e.detail.scrollTop : e.originalEvent ? e.originalEvent.detail.scrollTop : 0,
scrollLeft: e.detail ? e.detail.scrollLeft: e.originalEvent ? e.originalEvent.detail.scrollLeft : 0
});
});
$scope.$parent.$on('scroll.resize', scrollViewResize);
// Called to stop refreshing on the scroll view
$scope.$parent.$on('scroll.refreshComplete', function(e) {
scrollView.finishPullToRefresh();
});
$scope.$parent.$on('scroll.anchorScroll', function() {
var hash = $location.hash();
var elm;
//If there are multiple with this id, go to first one
if (hash && (elm = $document.body.querySelectorAll('#' + hash)[0])) {
var scroll = ionic.DomUtil.getPositionInParent(elm, scrollEl);
scrollView.scrollTo(scroll.left, scroll.top);
} else {
scrollView.scrollTo(0,0);
}
});
/**
* Called to scroll to the top of the content
*
* @param animate {boolean} whether to animate or just snap
*/
$scope.$parent.$on('scroll.scrollTop', function(e, animate) {
scrollViewResize().then(function() {
scrollView.scrollTo(0, 0, animate === false ? false : true);
});
});
$scope.$parent.$on('scroll.scrollBottom', function(e, animate) {
scrollViewResize().then(function() {
var sv = scrollView;
if (sv) {
var max = sv.getScrollMax();
sv.scrollTo(0, max.top, animate === false ? false : true);
}
});
});
}
};
}]);
})(ionic);