In my AngularJS app, I have an about page with several sub-sections. All these sub-sections are on the same page and part of the same template. However I want to access each section via it's own URL that will scroll down to the correct section if it matches.
I've set up the states as so:
.state('about', {
url: "/about",
templateUrl: "partials/about.html",
})
.state('about.team', {
url: "/about/team",
templateUrl: "partials/about.html"
})
.state('about.office', {
url: "/about/office",
templateUrl: "partials/about.html"
})
.state('about.other', {
url: "/about/other",
templateUrl: "partials/about.html"
});
And on the about page I have a menu like:
<div class="menu">
<a ui-sref-active="selected"
ui-sref="about.team">The Team</a>
<a ui-sref-active="selected"
ui-sref="about.office">The Office</a>
<a ui-sref-active="selected"
ui-sref="about.other">Other</a>
</div>
This menu is fixed at the bottom and when the user clicks the link or when visiting the url direct via the address bar it should scroll to that section (updating the url where need be to match it).
However I'm not sure how to do this (via Angular). To summarize:
The HTML for the page looks Like: http://pastebin.com/Q60FWtL7
You can see the app here: http://dev.driz.co.uk/AngularPage/app/#/about
For an example of something similar (https://devart.withgoogle.com/#/about/your-opportunity) as you can see it scrolls down to the correct section based on the url AFTER the page has loaded... and doesn't use a hash but the ACTUAL url.
You can try this approach where you create a directive which triggers the scroll on click. You can add this directive to your link as an attribute. where the sref attribute will be the id of the target div.
app.directive('scrollTo', function() {
return {
link: function(scope, element, attrs) {
element.bind('click', function() {
var divPosition = $(attrs.sRef).offset();
$('html, body').animate({
scrollTop: divPosition.top
}, "slow");
});
}
};
});
Plunker
ui-router doesn't place restrictions on the signature of your state object, so you can simply add a property:
.state('about.office', {
url: "/about/office"
,templateUrl: "partials/about.html"
,scrollToId = "divAboutOffice";
})
Then your controller can access this data when you inject the $state service.
$('html, body').animate({
scrollTop: $($state.current.scrollToId).offset().top
}, "slow");
assuming you included the id="divAboutOffice"
in your HTML. (and assuming my jQuery reference was correct; I don't use jquery so I'm not sure.)
Depending on your needs, you would wrap that animate()
in an $on()
for one of the events: $locationChangeSuccess)
, $routeChangeSuccess
, or $stateChangeSuccess
also: You don't have to use the "id", as I have - You could leverage the existing ui-sref
if you really want to search for elements by attribute. In your example that appears to match $state.current.name
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With