如何从 Blazor WebAssembly 中的 Razor 页面访问 body 标签或其他标签?

Posted

技术标签:

【中文标题】如何从 Blazor WebAssembly 中的 Razor 页面访问 body 标签或其他标签?【英文标题】:How can I reach body tag or another tag from Razor Page in Blazor WebAssembly? 【发布时间】:2021-06-25 14:53:34 【问题描述】:

我正在尝试从 Razor 页面访问正文。我刚刚开始学习 Blazor。所以我不知道这是否可能。基本上我正在尝试从 C# 端和不同页面更改正文类。我可以用 javascript 来做,但我想用 Blazor WebAssembly 来做。如果正文在 Razor 页面内,它可以工作。但我不想那样使用它。

index.html

<!DOCTYPE html>
<html lang="tr">
<head>
    <meta charset="utf-8" />
</head>
<body class="theme-dark">
    <app>Loading...</app>
    <script src="_framework/blazor.webassembly.js"></script>
</body>
</html>

MainLayout.razor

@inherits LayoutComponentBase
<div class="grid-wrapper sidebar-bg bg1">
    <div id="theme-tab">
        <div class="theme-tab-item switch-theme bg-white" @onclick="ToggleTheme" data-theme="theme-default" title="Light"></div>
        <div class="theme-tab-item switch-theme bg-dark" @onclick="ToggleTheme" data-theme="theme-dark" title="Dark"></div>
    </div>
    <NavMenu />
    <SideBar />
    <div class="main">
        @Body
    </div>
    <Footer />
</div>

@code 
    private bool isDark = true;
    private string currentTheme => isDark ? "theme-dark" : "theme-default"; //I want to use this variable in other pages.

    private void ToggleTheme()
    
        isDark = !isDark;
    

【问题讨论】:

我假设您想在&lt;body&gt; 中更改它,而不是@body&lt;body&gt; 不是 Blazor 应用程序的一部分,因此如果没有一些 JSInterop,就无法在 Blazor 中进行更改。为什么不想在 Layout 中做呢? 【参考方案1】:

如果你想换掉&lt;body&gt;

添加一个 JS 文件。

site.js

window.SetBodyCss = function (elementId, classname) 
    var link = document.getElementById(elementId);
    if (link !== undefined) 
        link.className = classname;
    
    return true;

Host.cshtml 中引用它。 在&lt;body&gt; 上创建一个id

<body id="BlazorMainBody">

    <script src="/site.js"></script>
    <script src="_framework/blazor.server.js"></script>
</body>

添加帮助类

using Microsoft.JSInterop;
using System.Threading.Tasks;

namespace Blazor.Starter

    public class AppJsInterop
    
        protected IJSRuntime JSRuntime  get; 

        public AppJsInterop(IJSRuntime jsRuntime)
        
            JSRuntime = jsRuntime;
        

        public ValueTask<bool> SetBodyCss(string elementId, string cssClass)
          => JSRuntime.InvokeAsync<bool>("SetBodyCss", elementId, cssClass);
    

这显示在页面中切换它

<button type="button" @onclick="SetCss">SetCss</button>

@code 
    [Inject] private IJSRuntime _js  get; set; 

    private bool _isbodyCss;

    private string _bodyCss => _isbodyCss ? "Theme-Dark" : "Theme-Light";

    private async Task SetCss()
    
        var appJsInterop = new AppJsInterop(_js);
        await appJsInterop.SetBodyCss("BlazorMainBody", _bodyCss);
        _isbodyCss = !_isbodyCss;
    

您可以以类似的方式更改整个样式表 - 请参阅note of mine

【讨论】:

我只是不理解助手类部分。我没有添加那部分,它正在工作。谢谢你的回答。 它只是一个保存方法的构造。有些人喜欢使用辅助类。你直接调用它,没问题。我通常会。【参考方案2】:

将您的布局 HTML 包装在 &lt;body&gt; 标记中。

我需要 navbar-collapsed 类在某些布局中的 &lt;body&gt;navbar-expand 在某些布局中。默认情况下它是navbar-expand,所以在我需要折叠的其他布局中,我只是将我的布局 HTML 包装在带有class="navbar-collapsed"&lt;body&gt; 标记中,它就可以工作了。

【讨论】:

尽管所有 HTML 都应该在 &lt;body&gt; 标记中,除了 &lt;head&gt;&lt;html&gt;,无论布局/类如何。

以上是关于如何从 Blazor WebAssembly 中的 Razor 页面访问 body 标签或其他标签?的主要内容,如果未能解决你的问题,请参考以下文章

如何通过 Blazor WebAssembly 写入浏览器控制台?

Blazor Webassembly 中的 JavaScript 免费引导轮播

Angular 项目中的 Blazor webassembly

Blazor Webassembly:如何将组件插入字符串

为 Blazor WebAssembly 中的所有 blazor 页面实例化一个对象?

无法从 Visual Studio 2019 16.6.2 调试 Blazor 托管的 webassembly 3.2.0