Hash linking with routing - `$anchorScroll` troubleshooting
Asked Answered
K

2

1

Note: I still haven't solved this. This post seems to describe a solution to my problem since I'm using ngRoute and am on a newer version of Angular, but I couldn't make her solution work: https://mcmap.net/q/76887/-how-to-handle-anchor-hash-linking-in-angularjs

On my single page app: https://kylevassella.github.io/
I'm trying to link my nav buttons to hash links on a different view. I've been using the accepted answer here for help: How to handle anchor hash linking in AngularJS

But I'm having trouble implementing ($anchorScroll) on my site.

To see what I'm talking about:

  1. My Plunker: https://plnkr.co/edit/fgTG7j?p=info Make the preview window wide enough so the nav menu ('Home Portfolio Contact') appears at the top.
  2. Scroll down to ‘Projects’, click ‘Project 1’. This opens a new view & ng-show enables a different nav bar (which looks the same as the old. Look below <section ng-show="showPortfolioHeader"> in index.html for these nav anchors).

  3. From here I want ‘Portfolio’ & ‘Contact’ to link to the #portfolio & #contact hash link ID's in my views/home.html view. But they only take me to the correct route (views/home.html), not to their respective scroll points on the page.
    NOTE: On Plunker, these don't even link to the correct route, they bring me to a 404. That's not the problem - on my local machine this part works fine. My problem is that once I get to the views/home.html view, the browser isn't scrolling to the hash link.

Knar answered 5/1, 2017 at 20:42 Comment(1)
As a side note, plunker is great, but it's also a good idea to show some code directly in the question. E.g in this case it'd be the two ng-show, ng-hide nav blocks in question.Bivalve
B
1

Edit: I've been looking at this wrong the whole way.

You're never changing the route, that's why your scroller is not working.

Your initial menu is captured with regular anchorScroll stuff.

But when you later hide that one and "show portfolio header", you link to stuff which are not the new routes. <a href="/?scrollTo=contact"> is still a / route, it just has some params. So your route never changes and your router does not react.

Without going into details of why you have different menus, I'd say that in the portfolio header, you would be better off using ng-click instead of href there and trigger scroll programatically.

Or better yet, just merge the two menus, they seem similar enough. Just show-hide the hero container, not the whole menu.

If I understood the question correctly, this is your problem:

href="/?scrollTo=contact"

Change that to

href="#/?scrollTo=contact"

And your scrollTo works. That's because if your browser (e.g. Chrome) sees a href with a /?scrollTo=contact, it says "Ah, a real link! To / (or index.html. It navigates right away, without giving JavaScript (and angular) time to work.

But when you add a # in front of the link, browser doesn't navigate, it knows it needs to stay on the same page, just different anchor. And this now gives Angular time to catch your click and work with it.

As a side note: since your local dev environment probably redirects everything not matched to index.html, it's why that part of works locally - on plunker it tries to go to it's home page with that link, but they don't have it so it gives you 404.

Bivalve answered 9/1, 2017 at 9:54 Comment(6)
Thanks for your response. I've tried every combination of # and #! before the / to no avail when testing on my local machine via http-server. On my local tests, when I make it href=“#/?scrollTo=contact”, it stops redirecting at all. Only when I remove the # does it redirect to the proper view, but then I have the problem of it not scrolling to the hash link, as you described would happen (Angular and JS don’t have time to work). Does this mean that this strategy isn’t easily testable on my local machine and I need to upload it to test it?Knar
Last note - on my local testing the URL's have a hashbang #! rather than a hash - I don’t know the cause or if it has any significance. I've tried both #! and # before the / in my href and this causes the link to not work at all on my local machine.Knar
UPDATE: I've uploaded my project to the web for you to more easily see: kylevassella.github.io It still uses a hashbang rather than a single hash - I don't know the significance of this. On the specified nav items, you'll see that I've tried 3 different ways of using scrollTo= in the href. The only one which redirects the page is the 'Contact' button, which uses only a / in the href.Knar
@KyleVassella ah, I've forked the project, checked out locally, and found out the issue. You never get to change the route.Bivalve
I apologize for neglecting your answer - the week's been pretty hectic. I did try some things like removing my second nav but to no avail (you are right though, removing it is ideal). The URL at very top of my question leads to a post by a girl who said something similar (use ng-click, ). I tried but must have missed something. You say my route never changes. However when I use the <a href="/?scrollTo=contact"> I am taken from the JC-Reaty.html view to the home.html view. Doesn't this mean that the route changed, or not necessarily?Knar
BTW, part of her answer: Now (in newer Angular versions), $anchorScroll accepts the hash as an optional argument, so you don't have to change $location.hash at all. This is the best solution because it doesn't affect the route at all. I couldn't get any of the other solutions to work because I'm using ngRoute and the route would reload as soon as I set $location.hash(id), before $anchorScroll could do its magic. What do you think of her answer w regards to me? Applicable, or is it more toward what you said w/ regards to route not changing?Knar
T
1

Hi i dont know if you resolve it but this is what i did and it worked for me :)

<a ng-click="scrollTo($event, id)">dasdsa</>
<div id="id"></div>
/// ctrller
$scope.scrollTo = function(event, id){
   event.preventDefault();
   var old = $location.hash();
   $anchorScroll();
   $location.hash(old);
}
Trista answered 20/12, 2018 at 18:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.