javascript - Persisting scroll position in Angular after refresh -
i've got web app i've written angularjs: http://asmor.com/anr
this app helping build decks particular game.
when add cards deck, they're added fixed-positioned div in top right corner. div has dynamically-set max-height won't occluded bottom of browser's window or fixed div in bottom right corner of page.
if hit max height, list of cards in deck scrolls. see below:

now problem when add or remove card deck while it's scrolled clicking red or green buttons, angular redraws deck list , resets scroll top.
for convenience, here's code i'm using deck list:
<div id="deck" class="shown-{{ deck.notempty }} faction{{ deck.identity.faction }}"> <div class="deckstat cardtotal"> <strong class="valid-{{ deck.enoughcards }}">cards:</strong> {{ deck.cardcount }} / {{ deck.mincards }} </div> <div class="deckstat agendapointstotal shown-{{ deck.iscorp }}"> <strong class="valid-{{ deck.enoughagendapoints }}">agenda points:</strong> {{ deck.totalpoints }} / {{ deck.minpoints }} </div> <div class="deckstat influencepointstotal"> <strong class="valid-{{ deck.withininfluencelimit }}">influence points:</strong> {{ deck.influencetotal }} / {{ deck.influenceavailable }} </div> <div class="deckidentity" ng-mouseover="setpreviewlink(deck.identity)"> <strong>identity:</strong> {{ deck.identity.name }} </div> <div id="deckscrollcontainer" style="max-height: {{ getmaxdeckheight() }}px"> <ul ng-repeat="(typename, typehash) in deck.cardsbytype"> <li class="decktypeheader"> <strong>{{ typename }}</strong> <span class="quantity"> ({{ typehash.qty }}) </span> </li> <li ng-repeat="(cardname, qty) in typehash.cards" class="card faction{{ getcardfaction(cardname) }}" ng-mouseover="setpreviewlink(cardname)"> <button class="btn btn-mini btn-success add qty{{qty}}" ng-click="addcard(cardname)"><i class="icon-plus"></i></button> <button class="btn btn-mini btn-danger remove qty{{qty}}" ng-click="removecard(cardname)"><i class="icon-minus"></i></button> <span class="quantity"> {{ qty }}x </span> {{ cardname }} <span class="influence"> {{ getinfluencestring(cardname, qty) }} </span> </li> </ul> </div> </div> one thing i've tried adding function when add or remove cards grab current scroll position, , later on replace it.
$scope.addcard = function (c) { $scope.setdeckscroll(); $scope.deck.add(c); }; $scope.setdeckscroll = function () { $scope.deckscrollposition = document.getelementbyid("deckscrollcontainer").scrolltop; }; and...
$scope.getcardfaction = function (card) { $scope._persist(); card = getcardbyname(card); return card.faction; }; $scope._persist = function () { // weird stuff needs done on redraw/refresh if ($scope.deckscrollposition) { document.getelementbyid("deckscrollcontainer").scrolltop = $scope.deckscrollposition; $scope.deckscrollposition = null; } }; as far can tell, angular redrawing page many times when redraw it. don't know when last re-draw going be, , can't blindly set scrollposition every time because if scrolled top on own wouldn't able tell difference between , if had scrolled top because of redraw.
one option i've considered using settimeout clear $scope.deckscrollposition,
i able work clearing scroll position variable settimeout (so every redraw have access variable)
$scope._persist = function () { // weird stuff needs done on redraw/refresh if ($scope.deckscrollposition) { document.getelementbyid("deckscrollcontainer").scrolltop = $scope.deckscrollposition; settimeout(function () { $scope.deckscrollposition = null; }, 100); } }; ...but seems hacky. i'm hoping there might better way. ideas on how either...
make angular redraw once per change in data (e.g. maybe i've coded poorly that's forcing redraw multiple times?)
somehow cope redraw without resorting settimeout chicanery?
found answer here:
http://www.benlesh.com/2013/02/angular-js-scrolling-to-element-by-id.html
and example plunkr, little customised here:http://plnkr.co/edit/ctvgveoy7cnlx38o70i4?p=preview
basically, set location.hash , scroll it. hope works you, setup little more complex.
e: noticed focusses viewport on last item, in fact undesireable.
Comments
Post a Comment