通过 Interop 添加简单的 DOM 操作 JS 脚本

问题描述 投票:0回答:2

我正在尝试将此 Javascript 函数导入到我的 Blazor 应用程序中。脚本的功能很简单,将类

c-show
添加到已有两个类的现有列表
<li>
元素中。完成后的原始 javascript 是:

Javascript

document.addEventListener('DOMContentLoaded', (event) => {
    document.querySelectorAll('.c-sidebar-nav-item.c-sidebar-nav-dropdown').forEach(dropMenu => {
        dropMenu.addEventListener('click', () => dropMenu.classList.toggle('c-show'));
      });
    })

此脚本影响此元素:

<li class="c-sidebar-nav-item c-sidebar-nav-dropdown">

添加

c-show
使其:

<li class="c-sidebar-nav-item c-sidebar-nav-dropdown">

我正在尝试通过 Interop 使用 Blazor/C# 实现同样的目标。

所以我在我的元素中添加了以下内容:

<li class="c-sidebar-nav-item c-sidebar-nav-dropdown" @onclick="dropMenu">

我的代码部分是:

@code {

  public async void dropMenu() 
  {
    classList.toggle('c-show')
  }
}

但是我并不完全确定如何获得我正在工作的结果,因为我所知道的是我需要以某种方式调整 javascript,但不确定如何调整。

c# interop blazor
2个回答
0
投票

您可以使用 OnAfterRenderAsync 方法中的 JSInterop 调用来初始化您的 JavaScript 对象,这只能完成一次,然后您可以在每次渲染组件时调用您的 JavaScript 方法。

注意:您需要注入 JSRuntime 对象才能执行 JSInterop 调用。

 @page "/"
 @inject IJSRuntime jsRuntime

 <li id="myid" @ref=MyElementReference class="c-sidebar-nav-item c-sidebar- 
                                        nav-dropdown" @onclick="dropMenu"> 

@code{
    // This add an element reference to the li element, which you can pass to 
    // your JavaScript functions
    ElementReference MyElementReference;

    // You have to call your JavaScript code after your components have been 
    // rendered. The OnAfterRenderAsync method is called after the component 
    // has been rendered, and thus you can put code here to initialize your 
    // component. This should be when firstRender is true, and multiple calls 
    // to your JavaScript objects, when firstRender is false.

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        // Note: Here you initialize your elements, only once. When the user 
        // clicks on the li element, you'll call your required method from 
        // the click event handler dropMenu

        if (firstRender)
        {
            await JSRuntime.InvokeAsync<object>("MyJSMethods.myMethod", 
                    MyElementReference);
        }

    }
}



public async void dropMenu() 
  {
    await JSRuntime.InvokeAsync<object>("MyJSMethods.myMethod", 
                        MyElementReference);

  }

将脚本放在 _Host.cshtml 文件的底部,就在下面 相应地调整你的元素。请注意,此处的代码仅显示带有 li 标记的 id 的警报。相反,您必须添加代码来根据需要更改对象。

<script src="_framework/blazor.server.js"></script>
<script>
        window.MyJSMethods =
        {
            myMethod: function (element) {
                window.alert(element.id);
            }
        };
    </script>

请注意,该函数采用的名为 element 的参数是一个元素对象,因为我们在 Blazor 中将该参数定义为 ElementReference。当然,您可以传递元素 id 或类名等。


0
投票

更好的方法是创建一个包含以下内容的模块(例如

sidebar-dropdown.js
):

export function addCShowTogglers() {
    document.querySelectorAll('.c-sidebar-nav-item.c-sidebar-nav-dropdown').forEach(dropMenu => {
        dropMenu.addEventListener('click', () => dropMenu.classList.toggle('c-show'));
    });
}

下一步涉及创建一个组件,如下所示:

@implements IAsyncDisposable
@inject IJSRuntime jsRuntime

<ul>
    <li class="c-sidebar-nav-item c-sidebar-nav-dropdown">
        Content here
    </li>
    <li class="c-sidebar-nav-item c-sidebar-nav-dropdown">
        Content here
    </li>
    <li class="c-sidebar-nav-item c-sidebar-nav-dropdown">
        Content here
    </li>
</ul>

@code {
    private IJSObjectReference? _module;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            // this statement assumes the module is in the wwwroot/js folder
            _module = await jsRuntime.InvokeAsync<IJSObjectReference>("import", "/js/sidebar-dropdown.js");
            await _module.InvokeVoidAsync("addCShowTogglers");
        }
    }

    async ValueTask IAsyncDisposable.DisposeAsync()
    {
        if (_module != null)
        {
            // release unmanaged resources, eventually
            await _module.DisposeAsync();
            _module = null;
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.