0

我正在尝试调用一个 JS 函数,该函数通过 Blazor 中的 JS 互操作在用户单击时创建一个模式。问题是,该函数对 Blazor 子菜单内的 DOM 元素使用 onclick 事件。当该 DOM 元素位于侧面导航栏中的子菜单之外时,它可以正常工作。当我将该元素放入子菜单时,Blazor 抱怨它cannot set property 'onclick' of null

这是我的导航栏 HTML 和 JS 互操作代码

@inject IJSRuntime JS;

<div class="top-row pl-4 navbar navbar-dark">
    <a class="navbar-brand" href="">Test</a>
    <button class="navbar-toggler" @onclick="ToggleNavMenu">
        <span class="navbar-toggler-icon"></span>
    </button>
</div>

<div class="@NavMenuCssClass" @onclick="ToggleNavMenu">
    <ul class="nav flex-column">
        <li class="nav-item px-3">
            <NavLink class="nav-link" href="/" Match="NavLinkMatch.All">
                <span class="oi oi-home" aria-hidden="true"></span> Home
            </NavLink>
        </li>

        <li class="nav-item px-3">
            <NavLink class="nav-link" @onclick="()=>expandSubNav = !expandSubNav">
                <span class="oi oi-fork" aria-hidden="true"></span> AccountPage
            </NavLink>
            @if (expandSubNav)
            {
        <ul  class="nav flex-column" id="submenu">
            <li class="nav-item px-3">
                <a class="expand-menu" href="page">
                    <span>element1</span>
                </a>
            </li>
            <li class="nav-item px-3">
                <a class="expand-menu" href="page">
                    <span>element2</span>
                </a>
            </li>
            <li class="nav-item px-3">
                <a class="expand-menu" href="page">
                    <span>element3</span>
                </a>
            </li>
            <li class="nav-item px-3">
                <a class="expand-menu">
                   
                    <div   id="addBtn" ><span class="oi oi-plus" aria-hidden="true"></span> Add Element</div>
                    </a>
            </li>
      


        </ul>
            }
        </li>
       
        

    </ul>
</div>

<div id="myModal" class="modal">

    <!-- Modal content -->
    <div class="modal-content">
        <h1 class="modal-title">
            <b>Add Element Here</b>
        </h1>

        <input id="addelementtext" type="text" />
        <button id="add">Add</button>
        <button type="button" class="btn btn-defaultcloseissue" id="closebtn" data-dismiss="modal" onclick="">Close</button>



    </div>
</div>





    </div>
</div>
@code { private bool collapseNavMenu = true;
    private bool expandSubNav;

    private string NavMenuCssClass => collapseNavMenu ? "collapse" : null;

    private void ToggleNavMenu()
    {
        collapseNavMenu = !collapseNavMenu;
    }
    protected override async Task OnAfterRenderAsync(bool firstRender)
    {


        if (firstRender)
        {
            
                await JS.InvokeVoidAsync("createModal");
            
        }
    }

}

我正在尝试将 onclick 与此 id 元素一起使用

<li class="nav-item px-3">
                <a class="expand-menu">
                   
                    <div   id="addBtn" ><span class="oi oi-plus" aria-hidden="true"></span> Add Element</div>
                    </a>
            </li>

它位于它创建的子菜单中。当我将它放在子菜单之外的主导航菜单中时,JS 功能不会抱怨并且工作正常。

我也试过这样做

 protected override async Task OnAfterRenderAsync(bool firstRender)
    {


        if (firstRender)
        {
            if (expandSubNav)
            {
                await JS.InvokeVoidAsync("createModal");

            }
        }
    }

这会停止错误,但单击该元素不会执行任何操作。我该如何解决这个问题?我正在尝试研究 Blazor LifeCycle,因为我觉得这是一个渲染问题,但我很难理解我能做什么。

这也是我试图调用的 JS 函数

window.createModal = function createModal() {
    var modal = document.getElementById("myModal");

    // Get the button that opens the modal
    var btn = document.getElementById("addBtn");
    var closebtn = document.getElementById("closebtn");


    // When the user clicks the button, open the modal
    btn.onclick = function () {
        modal.style.display = "block";
    }



    // When the user clicks anywhere outside of the modal, close it
    window.onclick = function (event) {
        if (event.target == modal) {
            modal.style.display = "none";
        }
    }
    closebtn.onclick = function (event) {

        modal.style.display = "none";
    }
}
4

1 回答 1

1

您的第一个错误 ,cannot set property 'onclick' of null发生是因为在首次呈现导航栏时未展开子导航部分,因此addBtn当您调用时尚未在 DOM 中找到该元素var btn = document.getElementById("addBtn");

第二个问题是因为你的if()语句只运行一次,在第一次渲染时,whileexpandSubnav是错误的。所以你的await JS.InvokeVoidAsync("createModal");线永远不会被执行。

如果您在@code块中注意到有一种切换方法collapseNavMenu

private void ToggleNavMenu()
{
    collapseNavMenu = !collapseNavMenu;
}

如果您做了类似的事情,但对于expandSubnav,您可以利用它作为挂钩createModal代码的机会。你只想做一次,所以你可能也想跟踪它。就像是:

private bool modalCreated = false;
private void ToggleSubNav()
{
    expandSubnav = !expandSubnav;
    if(!modalCreated)
    {
        await JS.InvokeVoidAsync("createModal");
        modalCreated = true;
    }
}

然后将其连接到您的 NavLink:

<NavLink class="nav-link" @onclick="ToggleSubNav">
    <span class="oi oi-fork" aria-hidden="true"></span> AccountPage
</NavLink>
于 2021-03-12T23:44:30.980 回答