单击 Blazor 中的顶部导航链接时滚动到页面的指定部分

joh*_*jan 14 html css c# blazor

如何在 Blazor 中对已加载页面的一部分进行简单的“跳转”?在 HTML 中是这样的:

<a href="#contact">Contact us</a>
...
<section id="contact">
Run Code Online (Sandbox Code Playgroud)

理想情况下,我还希望平滑滚动到本节。以为我会尝试用 CSS 解决这个问题,但也许不可能?

Aar*_*don 8

我已经通过使用 a 解决了这个问题button,然后在标记中编写了一些内联 Javascript。您可以将其推广到 Blazor 组件以获得奖励积分!

<button type="button" onclick="document.getElementById('contact').scrollIntoView({behavior:'smooth'})">Contact us</button>
...
<section id="contact">
Run Code Online (Sandbox Code Playgroud)


Maj*_*jor 6

您可以使用2个Nuget包来解决这个问题:

  1. Scroll JSJsInterop Nuget的一部分。这有很多功能,请参阅文档,但主要部分是IScrollHandler可注入服务。您可以使用演示应用程序尝试一下。你可以看到scrollIntoView()和其他 JS 函数包裹在一起,可以平滑滚动。使用 JS 滚动支持更简单......
  2. 第二个选项是在带有“#”的 URL 中使用“ Parmalinks ”。Nuget可以在这里找到。这就是你所要求的。基本上它使用<a>标签,但您不必费心(请注意,即使演示应用程序也有# URL)。还呈现带有可点击图标和导航/复制操作的“链接”组件。当前平滑滚动不可用,但可以请求。您可以使用演示应用程序尝试一下。 模态演示


Isa*_*aac 5

您需要的是 Blazor 的散列路由功能。但是,唉,尚不存在这样的功能。我建议您使用 JSIterop 来执行此任务:创建一个执行导航的 JavaScript,并向其传递一个 ElementRef 对象。

希望这可以帮助...

编辑:以下是我在 Github 中找到的最佳解决方案的改编...

通常,当您单击要联系的链接时,您会被重定向到路由http://localhost:5000/mypage#contact,但会位于页面顶部。路由的片段不用于选择特定的 HTML 元素。

当前的解决方法是编写解释 URL 的显式代码。在上面的示例中,我们可以使用一点 JavaScript,然后从我们的 Blazor 代码中调用它:

我的页面.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();
    }
}
Run Code Online (Sandbox Code Playgroud)

索引.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>
Run Code Online (Sandbox Code Playgroud)

注意:如果您使用的是 Blazor .9.0 版,则应注入 IJSRuntime 请告诉我此解决方案是否适合您...


gok*_*ter 5

我使用了 Arron Hudon 的答案,但仍然不起作用。然而,经过尝试后,我意识到它不适用于锚元素:<a id='star_wars'>Place to jump to</a>。显然 Blazor 和其他 spa 框架在跳转到同一页面上的锚点时存在问题。为了解决这个问题,我必须使用段落元素(部分也可以)<p id='star_wars'>Some paragraph<p>:。

使用引导程序的示例:

<button class="btn btn-link" onclick="document.getElementById('star_wars').scrollIntoView({behavior:'smooth'})">Star Wars</button>

... lots of other text

<p id="star_wars">Star Wars is an American epic...</p>
Run Code Online (Sandbox Code Playgroud)

请注意,我使用 bootstrap 的btn-link类使按钮看起来像超链接。