Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Router: Provide support for handling the URL hash #6595

Closed
brandonroberts opened this issue Jan 20, 2016 · 87 comments
Closed

Router: Provide support for handling the URL hash #6595

brandonroberts opened this issue Jan 20, 2016 · 87 comments

Comments

@brandonroberts
Copy link
Collaborator

@brandonroberts brandonroberts commented Jan 20, 2016

If I have a URL with a hash, when I navigate to it, the hash is dropped from the URL and the page does not jump to the anchor tag. If I have to go an existing route and click a link with the hash at the end, it jumps to the anchor tag correctly. Also, their isn't a public api to get/set the hash outside of using window.location.hash

@ThiagoT1
Copy link

@ThiagoT1 ThiagoT1 commented Feb 21, 2016

+1

@tamalnath
Copy link

@tamalnath tamalnath commented Mar 1, 2016

Do we have any update on this?

@yeegr
Copy link

@yeegr yeegr commented Mar 19, 2016

Yes, I need this really quick as well.

@p-mcgowan
Copy link

@p-mcgowan p-mcgowan commented Apr 6, 2016

+1 please fix. This is mandatory for md-tab routing as well.

@afirdousi
Copy link

@afirdousi afirdousi commented Apr 8, 2016

Are there any plans on this ?

I was thinking on a few scenarios in my angular 2 prod app. As for designing a solution, will it makes sense to have these values on each route in @RouteConfig as well as when the user uses router.navigate(). The user should be allowed to navigate to a position or #hash, by default to the top (0,0)

It may look something like:

@RouteConfig([ { path: '/route1', component:Component1, name:'R1' }, // Scrolls to default (0,0) { path: '/route2', component:Component2, name:'R2', position:(0,600) }, // open at 600px vertically { path: '/route2', component:Component2, name:'R3', hash:"#about" } // opens at #about

and on router.navigate it may look like

this.router.navigate([ "R2" , { } , { position:(0,600) } ]) //or this.router.navigate([ "R3" , { } , { hash:"#about" } ])

I believe we need changes in Instruction and ComponentInstruction classes down i angular/route.

This or any other better solutions we implement, will it jump to the position or scroll smooth to the specified position. Idk.

@kucharzyk
Copy link

@kucharzyk kucharzyk commented Apr 21, 2016

+1
please fix this issue

@emesx
Copy link

@emesx emesx commented Apr 21, 2016

+1 (#8105)

@brandonroberts
Copy link
Collaborator Author

@brandonroberts brandonroberts commented Jun 24, 2016

Support for fragments has been added to the v3 router

@mark-langer
Copy link

@mark-langer mark-langer commented Jul 2, 2016

The router at release alpha.8 does update the URL - including the hash - correctly but does not make the view jump to the anchor specified by that hash.

Let's assume you are at this location:
www.example.org/Comp1/Comp2

Then clicking this link:
<a [routerLink]="['Comp3']" fragment="Test">Jump to 'Test' anchor </a>

will update the browser's url to:
www.example.org/Comp1/Comp2/Comp3#Test

So far, so good.

However, the view does not automatically scroll/jump to the element with id "Test". Are there any plans to fix this or am I just missing something?

@justme1
Copy link

@justme1 justme1 commented Jul 9, 2016

Using this._router.navigate( ['/feed', id ], {fragment: 'comments'});

How can I retrieve the fragment in ngOnInit so I can focus on the comments section?

@justme1
Copy link

@justme1 justme1 commented Jul 9, 2016

Found the answer:

http://victorsavkin.com/post/145672529346/angular-router

 constructor(private router:Router){
        const f: Observable<string> = _router.routerState.fragment;
        f.subscribe(params => {
             debugger; // params == 'comments'
        });
@goelinsights
Copy link

@goelinsights goelinsights commented Aug 22, 2016

@mark-langer did you ever get this working? Stuck in the same place where the #fragment works in the link but browser doesn't scroll to the id location.

@mark-langer
Copy link

@mark-langer mark-langer commented Aug 22, 2016

Nope, I just stumbled upon this issue on stackoverflow. I didn't need to fix this for my own application. I haven't tried it since alpha.8, though. Have you tried if this works with RC.5?

@goelinsights
Copy link

@goelinsights goelinsights commented Aug 22, 2016

It’s creating the #fragment in the route but not navigating to it via the angular router (v3) and I’m in RC4 currently. On page refresh it works, but that kind of defeats the point.

From: Mark Langer notifications@github.com
Reply-To: angular/angular reply@reply.github.com
Date: Monday, August 22, 2016 at 12:48 PM
To: angular/angular angular@noreply.github.com
Cc: Vijay Goel vijay@goelinsights.com, Comment comment@noreply.github.com
Subject: Re: [angular/angular] Router: Provide support for handling the URL hash (#6595)

Nope, I just stumbled upon this issue on stackoverflow. I didn't need to fix this for my own application. I haven't tried it since alpha.8, though. Have you tried if this works with RC.5?


You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or mute the thread.

{"api_version":"1.0","publisher":{"api_key":"05dde50f1d1a384dd78767c55493e4bb","name":"GitHub"},"entity":{"external_key":"github/angular/angular","title":"angular/angular","subtitle":"GitHub repository","main_image_url":"https://cloud.githubusercontent.com/assets/143418/17495839/a5054eac-5d88-11e6-95fc-7290892c7bb5.png","avatar_image_url":"https://cloud.githubusercontent.com/assets/143418/15842166/7c72db34-2c0b-11e6-9aed-b52498112777.png","action":{"name":"Open in GitHub","url":"https://github.com/angular/angular"}},"updates":{"snippets":[{"icon":"PERSON","message":"@mark-langer in #6595: Nope, I just stumbled upon this issue on stackoverflow. I didn't need to fix this for my own application. I haven't tried it since alpha.8, though. Have you tried if this works with RC.5?"}],"action":{"name":"View Issue","url":"https://github.com/angular/angular/issues/6595#issuecomment-241527913"}}}

@mark-langer
Copy link

@mark-langer mark-langer commented Aug 22, 2016

Yes, absolutely agreed. Maybe the Chuck Norris of routing, @brandonroberts, can help?

@ctrimm ctrimm mentioned this issue Jun 6, 2018
0 of 3 tasks complete
jasonaden added a commit to vsavkin/angular that referenced this issue Jun 7, 2018
For documentation, see `RouterModule.scrollPositionRestoration`

Fixes angular#13636 angular#10929 angular#7791 angular#6595
mhevery added a commit that referenced this issue Jun 8, 2018
For documentation, see `RouterModule.scrollPositionRestoration`

Fixes #13636 #10929 #7791 #6595

PR Close #20030
@brandonroberts
Copy link
Collaborator Author

@brandonroberts brandonroberts commented Jun 8, 2018

Fixed via #20030

@rtm
Copy link

@rtm rtm commented Sep 22, 2018

@brandonroberts I'm confused. You say this is "fixed", pointing to a patch which restores scroll position when returning to a page, but isn't this issue (see the title) originally about correct handling of hashes (fragments), or am I missing something?

@brandonroberts
Copy link
Collaborator Author

@brandonroberts brandonroberts commented Sep 24, 2018

@rtm the PR adds support for handling fragments in addition to restoring thr scroll position when navigating between pages.

@SteamWind
Copy link

@SteamWind SteamWind commented Nov 1, 2018

So this isn't fixed... Or mistitled

@trotyl
Copy link
Contributor

@trotyl trotyl commented Nov 1, 2018

@SteamWind This issue is only about scroll position, so what do you expect?

@SteamWind
Copy link

@SteamWind SteamWind commented Nov 8, 2018

Maybe I misunderstood. Is it now possible to scroll to an hash when your already on the same route?

@trotyl
Copy link
Contributor

@trotyl trotyl commented Nov 8, 2018

Fragments are also part of the URL:

await router.navigateByUrl('/aa#marker2');
expect(window.scrollY >= 5900).toBe(true);
expect(window.scrollY < 6000).toBe(true); // offset
await router.navigateByUrl('/aa#marker3');
expect(window.scrollY >= 8900).toBe(true);
expect(window.scrollY < 9000).toBe(true);

@MrGrigri
Copy link

@MrGrigri MrGrigri commented Nov 8, 2018

@trotyl, this is not just about the scroll position. This is about 'Provide support for handling the URL hash' as described in the beginning. IMO, this has not been addressed properly. Take this example. This is most commonly handled by a skip-link. In my example, I've made the skip-link visible and then pushed everything down. If I try to use the router.navigateByUrl() method, nothing happens.

@trotyl
Copy link
Contributor

@trotyl trotyl commented Nov 9, 2018

@MrGrigri URL hash is about scroll position, isn't it? Or what are the other semantics a fragment defined by standards? And that's what anchorScroll feature meant for.

If you have extra assumption about the fragment, that's already your own business logic. It could be fine to open new feature request for them, but which is indeed not part of this issue talking about:

If I have a URL with a hash, when I navigate to it, the hash is dropped from the URL and the page does not jump to the anchor tag.

@MrGrigri
Copy link

@MrGrigri MrGrigri commented Nov 9, 2018

Thanks @trotyl, I wasn't aware of the anchorScroll feature. I was able to get the scolling to work. However, there are still two things that don't work regarding the standard for navigating to a fragment. Mainly focus, and the CSS :target selector.

Should I open a new issue to cover these two?

@trotyl
Copy link
Contributor

@trotyl trotyl commented Nov 10, 2018

It's a browser bug that :target selector doesn’t work with History API, see #21193 for more information.

@MrGrigri
Copy link

@MrGrigri MrGrigri commented Nov 10, 2018

And what about the focus? It should focus the targeted element so when the tab key is pressed on the keyboard it continues from there. This is critical for accessibility.

@trotyl
Copy link
Contributor

@trotyl trotyl commented Nov 17, 2018

Sounds reasonable to me, better to open a new feature request for focusing behavior. It would likely also be put behind a flag for non-breaking requirement.

@phutaneVinayak
Copy link

@phutaneVinayak phutaneVinayak commented Dec 14, 2018

i did as following
in -- header.component.html
<a class="nav-link" [routerLink]="['about-us']" fragment="contact-us" preserveFragment> Contact Us</a>

in about-us.component.html
<section id="contact-us" class="bg-white"></section>

hash is not adding in router.
Any suggestion ?

i am new bee in angular. :)

@phutaneVinayak
Copy link

@phutaneVinayak phutaneVinayak commented Dec 14, 2018

i did as following
in -- header.component.html
<a class="nav-link" [routerLink]="['about-us']" fragment="contact-us" preserveFragment> Contact Us</a>

in about-us.component.html
<section id="contact-us" class="bg-white"></section>

hash is not adding in router.
Any suggestion ?

i am new bee in angular. :)

issue resolve. i did it as following :-

first i remove routerLink from a tag and add function on it .
<a class="nav-link" (click)="navigateToContactUs()" >Contact Us</a>

and in the function
this.router.navigate(['about-us'], {fragment: 'contact-us'})

and the result is
http://localhost:4200/about-us#contact-us

@cbejensen
Copy link

@cbejensen cbejensen commented Apr 22, 2019

I am doing what @phutaneVinayak suggested, and I do see the URL update with the fragment, but I do not see it scroll to that fragment's corresponding element. Here's an example.

Both of these produce the fragment in the URL, but neither seems to scroll the page:

this.router.navigate(['/'], { fragment: 'test' });
this.location.go('#test');

I know the HTML element is ID'd correctly because if I click in the address bar and hit Enter, it works.

@phutaneVinayak
Copy link

@phutaneVinayak phutaneVinayak commented Apr 23, 2019

I am doing what @phutaneVinayak suggested, and I do see the URL update with the fragment, but I do not see it scroll to that fragment's corresponding element. Here's an example.

Both of these produce the fragment in the URL, but neither seems to scroll the page:

this.router.navigate(['/'], { fragment: 'test' });
this.location.go('#test');

I know the HTML element is ID'd correctly because if I click in the address bar and hit Enter, it works.

Hi @cbejensen. I am working on your stackBiltz, seem you are using angular 4 and it does not provide

 anchorScrolling: 'enabled'  
options in routing config. so it will not definitely scroll to that id element. I need to find some workaround for that. give some time

HappyCoding

@phutaneVinayak
Copy link

@phutaneVinayak phutaneVinayak commented Apr 23, 2019

I am doing what @phutaneVinayak suggested, and I do see the URL update with the fragment, but I do not see it scroll to that fragment's corresponding element. Here's an example.

Both of these produce the fragment in the URL, but neither seems to scroll the page:

this.router.navigate(['/'], { fragment: 'test' });
this.location.go('#test');

I know the HTML element is ID'd correctly because if I click in the address bar and hit Enter, it works.

Hi, @cbejensen
I found the solution. Please check below code. It might be not a good way but it's solving the problem.

 
    this.router.navigate(['/'], {fragment: 'test'}).then(res => {
      console.log(res);
        let testElement = document.getElementById('test');
        console.log("testElement", testElement)
        if (testElement != undefined) testElement.scrollIntoView();
    })
 
@janstapel
Copy link

@janstapel janstapel commented Aug 8, 2019

Hi, @cbejensen
I found the solution. Please check below code. It might be not a good way but it's solving the problem.


   this.router.navigate(['/'], {fragment: 'test'}).then(res => {
     console.log(res);
       let testElement = document.getElementById('test');
       console.log("testElement", testElement)
       if (testElement != undefined) testElement.scrollIntoView();
   })

You don't even need the hash for that.. for me that looks elegant (but idk if it's good practice to navigate within pages without indicating it in URL)..
It neither looks very efficient so another solution for that would be nice..

 this.router.navigate([target]).then(()=>{
  window.location.hash=fragment;	
 });

Is also working.. but not if you want to navigate directly to a position of a page, coming from a different route..

@angular-automatic-lock-bot
Copy link

@angular-automatic-lock-bot angular-automatic-lock-bot bot commented Sep 15, 2019

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 15, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
You can’t perform that action at this time.