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

amrnrhlw  于 2023-04-13  发布在  其他
关注(0)|答案(6)|浏览(255)

如何在Blazor中对已经加载的页面进行简单的“跳转”?在HTML中如下所示:

<a href="#contact">Contact us</a>
...
<section id="contact">

理想情况下,我也想让它平滑地滚动到这个部分。我想我会尝试用CSS解决这个问题,但也许不可能?

b4lqfgs4

b4lqfgs41#

我已经通过使用button并在标记中编写一些内联Javascript解决了这个问题。

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

omhiaaxx2#

您需要的是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,你应该注入IJSHruntime请让我知道这个解决方案是否适合你...

gkl3eglg

gkl3eglg3#

你可以使用两个Nuget包来解决这个问题:
1.滚动JS这是JsInterop Nuget的一部分。这有许多功能,请参阅文档,但主要部分是IScrollHandler这是一个可注入的服务。你可以尝试与演示应用程序。你可以看到scrollIntoView()和其他JS功能 Package ,平滑滚动可用。所以更简单地使用JS滚动支持...
1.第二个选择是在你的URL中使用“Parmalinks”,你有“#”。这里有Nuget。这是你所要求的。基本上它使用的是<a>标签,但你不必为此烦恼(注意,即使是演示应用程序有#网址)。还呈现“链接”组件与可点击的图标和导航/复制动作。目前平滑滚动不可用,但可以请求。您可以使用演示应用程序进行尝试。x1c 0d1x

w8f9ii69

w8f9ii694#

我使用了Arron Hudon的答案,它仍然不起作用。然而,在玩了一圈之后,我意识到它不会与锚元素一起工作:<a id='star_wars'>Place to jump to</a>。显然Blazor和其他spa框架在同一页面上跳转到锚点时会出现问题。为了解决这个问题,我不得不使用段落元素(section也可以):<p id='star_wars'>Some paragraph<p>
使用bootstrap的示例:

<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>

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

baubqpgj

baubqpgj5#

答案与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);
}

}

1sbrub3j

1sbrub3j6#

最简单的方法如下:
1.在你的项目中添加一个javascript文件。
1.在其中添加以下函数:

function ScrollTo(elementId) {
var element = document.getElementById(elementId);
element.scrollIntoView({
behavior: 'smooth'
});}

1.将脚本引用添加到index.html中:

<script src="JavaScript.js"></script>

1.回到你的页面,在你的链接上添加一个onclick事件:

<a @onclick="(async() => await ScrolltoContact())">Contact</a>

1.进样IJS运行时间:

@inject IJSRuntime javaScript;

1.创建调用javascript函数的方法:

async Task ScrolltoContact()
{
    await javaScript.InvokeVoidAsync("ScrollTo", "Contact");
}

相关问题