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的主要内容,如果未能解决你的问题,请参考以下文章