Created
June 8, 2016 16:05
-
-
Save bdirito/e25b8fafe7363a0662e17d3b96a61ffa to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# based on ion-sticky | |
# this is heavily modified however as ion-sticky does not work with | |
# collection-repeat. To make this work we make the assumption that | |
# if an element is removed from the 'top' of the list it does NOT | |
# cease to be there. (collection-repeat prunes the top as it goes out of | |
# scroll) | |
define ['ionic'], -> | |
angular.module 'bl-ion-sticky', ['ionic'] | |
.directive 'blIonSticky', ($ionicPosition) -> | |
'ngInject' | |
restrict: 'A' | |
require: '^$ionicScroll' | |
link: ($scope, $element, $attr, $ionicScroll) -> | |
scroll = angular.element $ionicScroll.element | |
clone = null | |
createStickyClone = (element) -> | |
clone = angular.copy element | |
.css | |
position: 'absolute' | |
top: "#{$ionicPosition.position(scroll).top}px" | |
left: 0 | |
right: 0 | |
.addClass $attr.blIonStickyClass ? 'assertive' | |
.removeAttr 'ng-repeat-start' | |
.removeAttr 'ng-if' | |
scroll.parent().append clone | |
# compile the clone to put in angular .. really? | |
# we dont need - so removing | |
# $compile(clone) $scope | |
return clone | |
removeStickyClone = -> | |
if clone | |
clone.remove() | |
clone = null | |
lastActive = null | |
return | |
$scope.$on 'destroy', -> | |
removeStickyClone() | |
angular.element $ionicScroll.element | |
.off 'scroll' | |
return | |
updateSticky = ionic.throttle -> | |
active = null | |
itemDividers = $ $element | |
.find '.item-divider' | |
dividers = [] | |
# get a listing of all the dividers | |
for d in itemDividers | |
d = $ d | |
parentXform = d.parent().css 'style' | |
if not parentXform or ~parentXform.indexOf '-9999' | |
dividers.push d | |
# find out if there is any elements above the threshold of viewability - if so get the last one | |
for d, i in dividers | |
d = $ d | |
next = $ dividers[i + 1] | |
if $ionicPosition.offset(d).top - d.outerHeight() < 0 # the current item is not above the top | |
if i == dividers.length - 1 or ($ionicPosition.offset(next).top - next.outerHeight() > 0) # and the next one is not above the top | |
active = d | |
break | |
# see if we should *change* the clone in the dom; and do it ifso | |
# TODO: the .find(.collection-repeat-container) is fragile - but we are not actually garunteed any .item-dividers, so keep it for now | |
if $ionicPosition.offset($element).top < $ionicPosition.offset($element.find('.collection-repeat-container')).top | |
removeStickyClone() | |
else if active and active != lastActive | |
removeStickyClone() | |
lastActive = active | |
createStickyClone active | |
# push the clone up when a new one comes in from below | |
if clone and next and ($ionicPosition.offset(next).top < $ionicPosition.offset(clone).top + clone.outerHeight()) | |
cloneTop = Number.parseInt clone.css 'top' | |
clone.css 'top', cloneTop + $ionicPosition.offset(next).top - ($ionicPosition.offset(clone).top + clone.outerHeight()) | |
, 50 # note i reduced a 200 ms orig rate down to 50ms so the 'pushing' behaviour would look smoother | |
scroll.on 'scroll', (event) -> | |
updateSticky() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
just as a warning - this is intended as an example not production code. Ill not be updating this gist if/when I find & fix bugs