【问题标题】:Javascript click event not working in Blazor client side appJavascript 点击事件在 Blazor 客户端应用程序中不起作用
【发布时间】:2020-05-20 16:13:51
【问题描述】:

我是 Blazor 的新手,我创建了一个非常简单的 Webassembly 应用程序。当我点击它时,我想要一个 href 链接转到页面下方的 div,但 Javascript 点击事件不起作用。在 Index.razor 页面中,JsRuntime.InvokeVoidAsync("clicker") 正在工作,alert("In clicker") 在页面加载时发生,但点击/href 进入“intro”div 对爱情和金钱都不起作用:-/

index.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 部分位于页面顶部)

@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");
    }
}

如果有人能对此有所了解,那将节省我的一周时间。

【问题讨论】:

标签: javascript asp.net-core blazor blazor-client-side


【解决方案1】:

这里不需要 JavaScript。

如果您将特定目标添加到您的标记中,它就会起作用。

您可以使用 target="_top" 来避免 Blazor 导航拦截。

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

请注意,target="_top" 只是指示浏览器在窗口的最顶部框架内导航,并不意味着您会滚动到顶部!

【讨论】:

    【解决方案2】:

    页面不会滚动到您在链接中指定的元素。这与 Blazor 和大多数其他 SPA 应用程序中路由的处理方式有关。一个简单的解决方案是您可以创建自己的 AnchorLink 组件并使用一点 JavaScript 互操作魔法。

    1.在Pages/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.在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

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

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

    【讨论】:

    • 感谢 Xing - 第一个答案有效,所以现在就继续,一两天后会尝试您的解决方案
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-05
    • 2020-05-17
    相关资源
    最近更新 更多