如何在Blazor中简单地“跳转”到已加载页面的一部分?在HTML中像这样:
<a href="#contact">Contact us</a>
...
<section id="contact">
理想情况下,我也希望顺利向下滚动到此部分。以为我会尝试用CSS解决这个问题,但也许不可能?
你需要的是Blazor的散列路线功能。但是,唉,还没有这样的功能。我建议您使用JSIterop来执行此任务:创建执行导航的JavaScript,并将其传递给ElementRef对象。
希望这可以帮助...
编辑:以下是我在Github找到的最佳解决方案的改编...
通常,当您单击要联系的链接时,您将被重定向到路线http://localhost:5000/mypage#contact,但将位于页面顶部。路径的片段不用于选择特定的HTML元素。
当前的解决方法是编写解释URL的显式代码。在上面的例子中,我们可以使用一点JavaScript,然后从我们的Blazor代码中调用它:
mypage.cshtml:
@page "/mypage"
@inject Microsoft.AspNetCore.Components.Services.IUriHelper UriHelper
<nav>
<a href="#contact">contact</a>
</nav>
<section>
<h2 id="contact">contact</h2>
</section>
@functions {
protected override void OnInit()
{
NavigateToElement();
UriHelper.OnLocationChanged += OnLocationChanges;
}
private void OnLocationChanges(object sender, string location) => NavigateToElement();
private void NavigateToElement()
{
var url = UriHelper.GetAbsoluteUri();
var fragment = new Uri(url).Fragment;
if(string.IsNullOrEmpty(fragment))
{
return;
}
var elementId = fragment.StartsWith("#") ? fragment.Substring(1) : fragment;
if(string.IsNullOrEmpty(elementId))
{
return;
}
ScrollToElementId(elementId);
}
private static bool ScrollToElementId(string elementId)
{
return JSRuntime.Current.InvokeAsync<bool>("scrollToElementId", elementId).GetAwaiter().GetResult();
}
}
index.html的:
<script>
window.scrollToElementId = (elementId) => {
console.info('scrolling to element', elementId);
var element = document.getElementById(elementId);
if(!element)
{
console.warn('element was not found', elementId);
return false;
}
element.scrollIntoView();
return true;
}
</script>
注意:如果你使用Blazor版本.9.0,你应该注入IJSRuntime请告诉我这个解决方案是否适合你...
与Issac的答案相同的答案,但需要更改一些代码。
我发现主要的问题是你需要它是异步的。 @johajan
@inject IJSRuntime JSRuntime
...
@functions {
protected override async Task OnInitAsync()
{
await base.OnInitAsync();
//NavigateToElement();
UriHelper.OnLocationChanged += OnLocationChanges;
}
private async Task OnLocationChanges(object sender, string location) => await NavigateToElement();
private async Task NavigateToElement()
{
var url = UriHelper.GetAbsoluteUri();
var fragment = new Uri(url).Fragment;
if(string.IsNullOrEmpty(fragment))
{
return;
}
var elementId = fragment.StartsWith("#") ? fragment.Substring(1) : fragment;
if(string.IsNullOrEmpty(elementId))
{
return;
}
await ScrollToElementId(elementId);
}
private Task<bool> ScrollToElementId(string elementId)
{
return JSRuntime.InvokeAsync<bool>("scrollToElementId", elementId);
}
}