【问题标题】:How can I open a new window without using JS如何在不使用 JS 的情况下打开新窗口
【发布时间】:2020-10-27 08:14:26
【问题描述】:

在 blazor 中,我使用 NavigationManager.NavigateTo(url) 来更改窗口位置,但我如何使用它打开具有指定 URL 的新选项卡,而无需在 OnAfterRenderAsync() 上调用 JS

【问题讨论】:

    标签: c# signalr blazor


    【解决方案1】:

    截至 2019 年 3 月 21 日,目前无法直接使用纯 Blazor 执行此操作,您需要使用 JSInterop。幸运的是,这很容易做到。在您的.razor 文件顶部添加

    @inject IJSRuntime JSRuntime;
    

    然后像这样使用它

    await JSRuntime.InvokeAsync<object>("open", url, "_blank");
    

    【讨论】:

    • 回滚到修订版 1 为 IJSRuntime does not have InvokeVoidAsync
    • 我必须在OnAfterRender 中使用还是可以通过点击运行它?
    • 只有当我点击页面内的某个地方时,Js才会打开一个新窗口,它不会在方法中自动执行:await JsRuntime.InvokeAsync&lt;object&gt;("open", new object[] { "https://google.com/", "_blank" });
    • 你应该可以在任何地方调用代码,但我推荐OnClick,否则大多数浏览器会阻止它,因为它可能不是用户发起的事件
    • 这确实有效,但最终会抛出 TaskCanceledException。我想我可以捕捉并忽略它,我只是想知道是否有办法防止异常?
    【解决方案2】:

    以前,此代码有效。

    await _jsRuntime.InvokeVoidAsync("open", new object[2] { url, "_blank" });
    

    目前,它现在导致未捕获的异常:

    > "TypeError: Converting circular structure to JSON
    

    我发现这里解释了这种行为 (https://github.com/dotnet/aspnetcore/issues/16632):

    这是因为 window.open 返回一个 WindowProxy 对象(参见 https://developer.mozilla.org/en-US/docs/Web/API/Window/open)。 WindowProxy 不是 JSON 可序列化的,因此不能用作返回 .NET 代码的价值。

    要解决这个问题,不要直接调用 window.open,而是调用一个 JS 你自己的函数,要么什么都不返回,要么返回一些东西 这是 JSON 可序列化的。

    根据上述建议,我在 index.html 中添加了以下内容:

    <script>
        window.blazorOpen = (args) => {
            window.open(args);
        };
    </script>
    

    并修改了我的 C# 代码隐藏调用以传递窗口参数:

    await _jsRuntime.InvokeVoidAsync("blazorOpen", new object[2] { url, "_blank" });
    

    现在,我们通过丢弃 window.open 返回的 WindowProxy 对象有效地避免了该问题,该对象以前返回给 InvokeVoidAsync 并且 .NET 试图(不成功)处理。

    【讨论】:

      【解决方案3】:

      使用时会得到TypeError: Converting circular structure to JSON

      await _jsRuntime.InvokeVoidAsync("open", new object[2] { url, "_blank" });
      

      await _jsRuntime.InvokeAsync<object>("open", url, "_blank");
      

      这是因为 window.open 返回一个 WindowProxy 对象(请参阅 https://developer.mozilla.org/en-US/docs/Web/API/Window/open)。 WindowProxy 不是 JSON 可序列化的,因此不能用作 .NET 代码的返回值。

      取自here

      要使用 javascript 函数解决此问题,我使用以下方法

      await JSRuntime.InvokeVoidAsync("eval", $"let _discard_ = open(`{url}`, `_blank`)");
      

      【讨论】:

      【解决方案4】:

      只需使用常规链接

      <a href="@Url" target="_blank">@UrlDescription</a>
      

      【讨论】:

      • 我想从 blazor @onclick 事件处理程序中的 C# 函数打开一个窗口
      • 好的,你要点击什么?
      • 现在可以使用 @onclick="@(async ()=&gt;await JSRuntime.InvokeAsync&lt;object&gt;("open", url, "_blank"))"
      • 我对你的设计感到困惑。您希望他们点击某些东西,但它不能是一个旨在满足您要求的元素?不管怎样,很高兴你快乐。
      • 那么一个链接是由 c# 在该函数中生成的,然后用户被重定向到该 url
      【解决方案5】:

      根据 API 的最新更改,这里是可行的解决方案,您可以在其中将任何自定义对象属性添加到 URL,如下所示:

          /// <summary>
          /// Show Link
          /// </summary>
          /// <returns></returns>
          private async Task ShowLink()
          {
              if (this.selectedItem != null)
              {
                  string url = $"https://example.com/sites/" + this.selectedItem.Id + "/SitePages/Reports/somepage.aspx";
                  //NavigationManager.NavigateTo(url, false);//opens the new page on same browser tab
                  string[] values = { url, "_blank" };
                  CancellationToken token = new CancellationToken(false);
                  await JSRuntime.InvokeAsync<object>("open", token, values);//opens the link in new browser tab
              }
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-05-15
        • 1970-01-01
        • 2017-10-29
        • 2021-08-22
        • 1970-01-01
        • 1970-01-01
        • 2022-08-16
        • 2010-12-09
        相关资源
        最近更新 更多