简体   繁体   English

Javascript 单击事件在 Blazor 客户端应用程序中不起作用

[英]Javascript click event not working in Blazor client side app

I'm new to Blazor and I've created a pretty simple Webassembly app.我是 Blazor 的新手,我创建了一个非常简单的 Webassembly 应用程序。 I want a href link to go to a div lower down the page when I click on it, but the Javascript click event won't work.当我点击它时,我想要一个 href 链接转到页面下方的 div,但 Javascript 点击事件不起作用。 In the Index.razor page the JsRuntime.InvokeVoidAsync("clicker") is working and the alert("In clicker") happens as the page loads, but the click / href to go the "intro" div will not work for love nor money :-/在 Index.razor 页面中, JsRuntime.InvokeVoidAsync("clicker")正在工作,并且在页面加载时发生alert("In clicker") ,但是点击/href 转到“介绍”div 对爱或钱 :-/

index.html索引.html

<!DOCTYPE html>
<html>
<head>
    <title>My Blazor App</title>
    <!--script type='text/javascript' src='./scripts/app.js'-->
</head>
<body>
    <app>Loading...</app>
    <script src="_framework/blazor.webassembly.js"></script>
    <script>
        function clicker() {
            alert("In clicker"); // this works
            document.getElementById('skip').onclick = function(e){
                alert("clicked"); // this works but the page still won't scroll to the "intro" div :(
            }
        }
        //clicker();
    </script>
</body>
</html>

Index.razor (@code section is at top of page) Index.razor(@code 部分位于页面顶部)

@page "/"
@code {
    [Inject]
    protected IJSRuntime JsRuntime { get; set; }

    protected override void OnAfterRender(bool firstRender)
    {
        if (firstRender)
        {
            JsRuntime.InvokeVoidAsync("clicker");
        }
    }
}

// This link won't go to the intro div when clicked :(
<a id="skip" class="skip" href="#intro">skip this bit</a>
...
<div id="intro" class="home">
...
</div>

Startup.cs启动文件

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
    }

    public void Configure(IComponentsApplicationBuilder app)
    {
        app.AddComponent<App>("app");
    }
}

If anyone could shed some light on this it would save my week.如果有人可以对此有所了解,那将节省我的一周。

There is no need for JavaScript here.这里不需要 JavaScript。

If you add a specific target to your markup, it will just work.如果您将特定目标添加到您的标记中,它就会起作用。

You can use target="_top" to avoid Blazor navigation interception.您可以使用 target="_top" 来避免Blazor导航拦截。

<a class="skip" href="#intro" target="_top">skip this bit</a>
...
<div id="intro" class="home">
...
</div>

Note that target="_top" just directs the browser to navigate within the topmost frame in the window, it does not mean you will scroll to the top!请注意, target="_top"只是指示浏览器在窗口的最顶层框架内导航,并不意味着您将滚动到顶部!

The page won't scroll to the element you've specified in the link.This has to do with how routing is handled in Blazor and most other SPA applications as well.该页面不会滚动到您在链接中指定的元素。这与 Blazor 和大多数其他 SPA 应用程序中路由的处理方式有关。 A simple solution is that you could create your own AnchorLink component and use a little bit of JavaScript interop magic.一个简单的解决方案是您可以创建自己的 AnchorLink 组件并使用一点 JavaScript 互操作魔法。

1.Create AnchorLink.razor in Pages/Shared AnchorLink.razorPages/Shared创建AnchorLink.razor

@code {

    public AnchorLink()
    {
        this.Attributes = new Dictionary<string, object>();
    }

    private string targetId = null;
    private bool preventDefault = false;

    /// <summary>
    /// This parameter supports arbitrary attributes.
    /// </summary>
    /// <remarks>
    /// Any attribute specified on the component, which is not defined as a parameter, whill be added to this dictionary.
    /// It is then uses as the source for attributes rendered onto the resulting HTML element below in the markup section
    /// of this component.
    /// For details, refer to <see cref="https://docs.microsoft.com/en-us/aspnet/core/blazor/components#attribute-splatting-and-arbitrary-parameters"/>.
    /// </remarks>
    [Parameter(CaptureUnmatchedValues = true)]
    public IDictionary<string, object> Attributes { get; set; }

    /// <summary>
    /// Supports child content for the component.
    /// </summary>
    /// <see cref="https://docs.microsoft.com/en-us/aspnet/core/blazor/components#child-content"/>
    [Parameter]
    public RenderFragment ChildContent { get; set; }

    [Inject]
    protected IJSRuntime JsInterop { get; set; }


    protected override void OnParametersSet()
    {
        string href = null;
        if (this.Attributes.ContainsKey("href"))
        {
            // If the href attribute has been specified, we examine the value of it. If if starts with '#'
            // we assume the rest of the value contains the ID of the element the link points to.
            href = $"{this.Attributes["href"]}";
            if (href.StartsWith("#"))
            {
                // If the href contains an anchor link we don't want the default click action to occur, but
                // rather take care of the click in our own method.
                this.targetId = href.Substring(1);
                this.preventDefault = true;
            }
        }
        base.OnParametersSet();
    }

    private async Task AnchorOnClickAsync()
    {
        if (!string.IsNullOrEmpty(this.targetId))
        {
            // If the target ID has been specified, we know this is an anchor link that we need to scroll
            // to, so we call the JavaScript method to take care of this for us.
            await this.JsInterop.InvokeVoidAsync("anchorLink.scrollIntoView", this.targetId);
        }
    }

}

<a href="" @onclick="this.AnchorOnClickAsync" @onclick:stopPropagation="false" />
<a @attributes="this.Attributes" @onclick="this.AnchorOnClickAsync" @onclick:preventDefault="this.preventDefault">Hello @this.ChildContent</a>

2.Add js in wwwroot/Index.html 2.在wwwroot/Index.html js

<script src="_framework/blazor.webassembly.js"></script>
<script>
    window.anchorLink = {
    scrollIntoView: function (elementId) {
        // This function is called from the AnchorLink component using JavaScript interop.
        // It will try to find an element using the ID given to the function, and scroll that
        // element into view, if an element is found.
        var elem = document.getElementById(elementId);
        if (elem) {
            elem.scrollIntoView();
            window.location.hash = elementId;
        }
    }
}
</script>

3. Index.razor Index.razor

<AnchorLink class="skip" href="#intro">skip this bit</AnchorLink>

Refer to https://mikaberglund.com/2019/12/28/creating-anchor-links-in-blazor-applications/参考https://mikaberglund.com/2019/12/28/creating-anchor-links-in-blazor-applications/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM