Random thoughts & observations

From the mundane to the profound and everything in between here’s what’s rocking our world

Scrolling to a page anchor in Ionic Framework

Posted: February 17, 2015
Written by: Saints At Play
Category: Ionic Framework

If you've been working with the Ionic Framework you'll be familiar with setting up AngularJS routes for your controllers and view templates which are then triggered with hyperlinks used within your App. The combination of Ionic and AngularJS makes this easy to implement but when it comes to scrolling to a particular anchor inside a view template things get a little trickier.

The problem

You implement your HTML anchor like so:

 <!-- We use the id as an anchor -->
 <section id="location-1">
   // Content displayed in here
 </section>

Then you implement your link, within the same page, to this anchor as follows:

 <a href="#location-1">View location 1</a>

What you would expect, as the default behaviour in a website, simply doesn't work within the context of Ionic/Angular.

The Angular routing logic that you establish within your App will treat the above hyperlink as a route and try to match a controller to that particular route. As it does not find that route the link will simply return you to the home screen of your App and screw up the navigation flow/user experience as a result.

Definitely not what you or the user expects.

The solution

In order to implement scrolling to page anchors we need to change, ever so slightly, how we approach the task.

The first thing we do is modify our link to use AngularJS's ng-click directive instead. Making this change allows us to customise the behaviour of our hyperlink:

 <a ng-click="scrollToAnchorWithinCurrentPage('location-1')">View location 1</a>

We call a custom function, that we are about to define in the controller associated with our view template, called scrollToAnchorWithinCurrentPage. This function will accept a single parameter which will be used to pass in the DOM ID of the target anchor that we want to be able to scroll to.

Additionally, in the view template that we have just modified, we need to make some minor adjustments to allow anchor scrolling to be implemented:

<ion-view title="Locations">
  <ion-content delegate-handle="content">
    <section ng-controller="PageController">
       // Content to be displayed inside here (including link/anchor)
    </section>
  </ion-content>
</ion-view>

What we have done in the above is to tell the Ionic Framework that in our App we want the Ionic Delegate service to control the scrolling for this particular template view (by using the delegate-handle attribute to target that template view using a specific identifier which we simply name as content).

We also assign the ng-controller directive to the section in which we want to assign scopes for functions and data specific to that template view.

In our controller for this view we implement the scrollToAnchorWithinCurrentPage function as follows:

.controller('PageController', function($scope, $location, $anchorScroll, $ionicScrollDelegate)
{

  $scope.scrollToAnchorWithinCurrentPage  = 	function(anchor) 
  {
    $location.hash(anchor);
    var handle                            = 	$ionicScrollDelegate.$getByHandle('content');
    handle.anchorScroll();
  };

}

Our PageController class accepts the following dependencies: $scope, $location, $anchorScroll and $ionicScrollDelegate.

If you're familiar with Angular you'll understand the importance of scopes. If not, then please view the following documentation to learn about execution context for expressions and methods.

The $location service extracts the URL we wish to use from the ng-click directive and makes that available to our scrollToAnchorWithinCurrentPage function so we can process the anchor value (using the hash method of this service, as shown in the above code snippet).

The $ionicScrollDelegate service then determines which scroll view is to be targeted (through use of the $getByHandle method) and assigns that to a variable which will be used by the $anchorScroll service to implement scrolling to the specified DOM element (which it calculates from the result of the $location.hash method).

Now you should have a fully functioning solution to anchor scrolling within your Ionic Framework App view template.

« Return to Posts

Comments

There are no comments

Posting comments after three months has been disabled.