Blazor University (39)JavaScript 互操作 —— 更新 document title

Posted dotNET跨平台

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Blazor University (39)JavaScript 互操作 —— 更新 document title相关的知识,希望对你有一定的参考价值。

原文链接:https://blazor-university.com/javascript-interop/calling-javascript-from-dotnet/updating-the-document-title/

更新 document title

源代码[1]

在创建 Blazor 布局[2]部分中,我们看到了 Blazor 应用程序如何存在于 html(或 cshtml)文档中,并且只能控制主应用程序元素中的内容。

不是单页应用程序的网站可以通过在 <head> 部分中添加 <title> 元素来指定要在浏览器选项卡中显示的文本,但我们的 Blazor 应用程序实际上并不导航到不同的服务器页面,因此它们都有与我们的应用程序启动时加载的文档标题相同。

我们现在将使用一个新的 <Document> 组件来解决这个问题,该组件将使用 JavaScript 互操作来设置 document.title,这将反映在浏览器的选项卡中。我们将其创建为 Blazor 服务器应用程序;它可以很容易地在可重用的组件库中创建,但我将把它作为练习留给你。

创建一个新的 Blazor 服务器应用程序,然后在 wwwroot 文件夹中创建一个 scripts 文件夹,并在其中使用以下脚本创建一个名为 DocumentInterop.js 的脚本。

var BlazorUniversity = BlazorUniversity || ;
BlazorUniversity.setDocumentTitle = function (title) 
  document.title = title;
;

这将创建一个名为 BlazorUniversity 的对象,该对象具有一个名为 setDocumentTitle 的函数,该函数接受一个新标题并将其分配给 document.title

接下来,编辑 /Pages/_Host.cshtml 文件并添加对我们新脚本的引用。

<script src="_framework/blazor.server.js"></script>
<script src="~/scripts/DocumentInterop.js"></script>

最后,我们需要 Document 组件本身。在 /Shared 文件夹中创建一个名为 Document.razor 的新组件并输入以下标记。

@inject IJSRuntime JSRuntime
@code 
  [Parameter]
  public string Title  get; set; 

  protected override async Task OnParametersSetAsync()
  
    await JSRuntime.InvokeVoidAsync("BlazorUniversity.setDocumentTitle", Title);
  

这段代码有一个故意的错误。运行应用程序,您将在调用 JSRuntime.InvokeVoidAsync 的行上看到 NullReferenceException

原因是 Blazor 在将控制权交给客户端之前在服务器上运行预渲染阶段。此预渲染的目的是从服务器返回有效的渲染 HTML,以便

  • 网络爬虫,例如谷歌,可以索引我们的网站。

  • 用户立即看到结果。

这里的问题是,当预渲染阶段运行时,没有浏览器可供 JSRuntime 进行互操作。可能的解决方案是

  1. 编辑 /Pages/_Host.cshtml 并将 <component type="typeof(App)" render-mode="ServerPrerendered" /> 更改为 <component type="typeof(App)" render-mode="Server"/>

优点: 一个简单的修复。

缺点: 谷歌等在访问我们网站的页面时不会看到任何内容。

  1. 重写 OnAfterRenderAsync 而不是 OnParametersSetAsync

#2是解决问题的正确方法。

@inject IJSRuntime JSRuntime
@code 
  [Parameter]
  public string Title  get; set; 

  protected override async Task OnAfterRenderAsync(bool firstRender)
  
    if (firstRender)
      await JSRuntime.InvokeVoidAsync("BlazorUniversity.setDocumentTitle", Title);
  

正如在 JavaScript 启动过程一节中所解释的,当服务器在发送网站之前预渲染网站时,客户端浏览器将在没有任何 JavaScript 的情况下渲染 App 组件。只有在浏览器中呈现 HTML 后,才会调用 OnAfterRender* 方法并将 firstRender 设置为 true

使用新的 Document 组件

编辑 /Pages 文件夹中的每个页面,并添加我们的新元素 <Document Title="Index"/> - 但显然您希望在浏览器的选项卡中显示正确的文本。

参考资料

[1]

源代码: https://github.com/mrpmorris/blazor-university/tree/master/src/JavaScriptInterop/UpdatingDocumentTitle

以上是关于Blazor University (39)JavaScript 互操作 —— 更新 document title的主要内容,如果未能解决你的问题,请参考以下文章

Blazor University (31)表单 —— 验证

Blazor University (27)路由 —— 检测导航事件

Blazor University (26)路由 —— 通过代码导航

Blazor University (45)依赖注入 —— 将依赖项注入 Blazor 组件

Blazor University 组件 — 创建组件

Blazor University (36)组件库