As you may know, Blazor does not currently support navigation via anchors. In addition, Blazor does not support hyperlinks that only include anchor IDs within the href
attribute (<a href=”#MyAnchor1”>some text</a>
). To help address these limitations, we created a free navigation tool for both client-side and server-side Blazor projects.
Features and Capabilities
The DevExpress Anchor Navigation tool automatically scrolls a page to an anchor in the following instances:
- When an end-user clicks a hyperlink with an anchor;
- When a page is first opened and contains an anchor ID within its URL (for instance,
https://demos.devexpress.com/blazor/SchedulerViewTypes#DayView
).
Our tool also includes a Blazor AnchorLink
component. Use this component to create in-page navigation links as needed:
<AnchorLink class="nav-link py-3 px-4" href="#MySection1">My Section 1</AnchorLink> <AnchorLink class="nav-link py-3 px-4" href="#MySection2">My Section 2</AnchorLink>
When an end-user clicks the link, the page scrolls to the corresponding anchor:
<h2 id="MySection1">Section 1</h2> <p>Lorem ipsum dolor sit amet...</p> <h2 id="MySection2">Section 2</h2> <p>Quisque imperdiet risus quis nisl vulputate...</p>
Integrating the Anchor Navigation Tool
Full source code for our Blazor Anchor Navigation tool is available on GitHub. Please follow the instructions below to include it within your next Blazor project.
- Download the DevExpress.Blazor.AnchorUtils project and add it to your Blazor solution.
- Add the
DevExpress.Blazor.AnchorUtils
namespace to _Imports.razor:
@using DevExpress.Blazor.AnchorUtils
- Add
AnchorUtilsComponent
to Shared/MainLayout.razor file:
<div> ... <div class="content px-4"> @Body </div> </div> <AnchorUtilsComponent />
- Find the JavaScript wwwroot/anchor-utils.js file in the anchor navigation source code. Copy this file to the wwwroot folder or to its subfolders.
- For server-side Blazor: register this file in Pages/_Host.cshtml of your project.
- For client-side Blazor: register this file in wwwroot/index.html of your project.
<script type="text/javascript" src="~/anchor-utils.js"></script>
- (optional) If your page layout contains a pinned (non-scrollable) header (like the standard Blazor project), edit the anchor-utils.js file and update the following code to obtain vertical scroll offset appropriate for your application:
y -= document.querySelector(".main .top-row").offsetHeight;
How it works
First, we need to obtain an anchor from the current URI (if it exists). We’ll use the IUriHelperOnLocationChanged
event event to do so:
@inject IUriHelper UriHelper ... @code { string Anchor { get; set; } bool ForceScroll { get; set; } protected override void OnInitialized() { base.OnInitialized(); ForceScroll = true; UriHelper.OnLocationChanged += OnLocationChanged; } void OnLocationChanged(object sender, LocationChangedEventArgs args) { var anchor = UriHelper.ToAbsoluteUri(args.Location).Fragment; ... } }
The ScrollToAnchor
C# method invokes the scrollToAnchor
JavaScript function and sends an anchor ID as a parameter:
... @inject IJSRuntime JSRuntime @inject IComponentContext ComponentContext ... bool ScrollToAnchor(string anchor) { if (ComponentContext.IsConnected && (!string.IsNullOrEmpty(anchor) || ForceScroll)) { JSRuntime.InvokeAsync<string>("scrollToAnchor", anchor); return true; } return false; }
We’ll call the ScrollToAnchor
method in the OnLocationChanged
event handler to scroll the page when navigation location changes. We’ll also call the method in the OnAfterRenderAsync
event handler to initiate scrolling (if necessary) when a page first loads:
protected override Task OnAfterRenderAsync() { ScrollToAnchor(Anchor); if (ForceScroll) { ForceScroll = false; } return base.OnAfterRenderAsync(); } void OnLocationChanged(object sender, LocationChangedEventArgs args) { var anchor = UriHelper.ToAbsoluteUri(args.Location).Fragment; if (!ScrollToAnchor(anchor)) { Anchor = anchor; } }
The scrollToAnchor
JavaScript function scrolls to the required anchor element.
Javascript:
function scrollToAnchor(anchor) { var selector = anchor || document.location.hash; if (selector && selector.length > 1) { var element = document.querySelector(selector); if (element) { var y = element.getBoundingClientRect().top + window.pageYOffset; /* The following code updates the vertical scroll bar's offset for a standard Blazor Visual Studio template. Update the code to get an offset that is suitable for your application. */ y -= document.querySelector(".main .top-row").offsetHeight window.scroll(0, y); } } else { window.scroll(0, 0); } }
Feedback
As always, your feedback matters. Do you plan on using anchors in your Blazor applications? Post your comments below and share your Blazor-related development experiences with us.