Blazor JSInterop 从 DOM 获取元素属性

Blazor JSInterop Getting Element Attributes from the DOM

提问人:Glen Hamblin 提问时间:11/10/2023 最后编辑:Glen Hamblin 更新时间:11/10/2023 访问量:37

问:

我使用 Visual Studio 2022 样板项目制作了一个 Blazor 服务器端 Web 应用。我仍在使用 .NET 7,因为我的公司更新速度很慢。

我按照本教程使用 JSInterop 从 DOM 获取窗口的尺寸。然后,我尝试调整代码以获取特定元素的尺寸。我有以下文件:

MyApp/Services/BrowserService.cs


using Microsoft.JSInterop;
public class BrowserService
{
    private readonly IJSRuntime _js;

    public BrowserService(IJSRuntime js)
    {
        _js = js;
    }

    public async Task<RectDimension> GetRectDimensions()
    {
        return await _js.InvokeAsync<RectDimension>("getRectDimensions");
    }
    public async Task<BrowserDimension> GetBrowserDimensions()
    {
        return await _js.InvokeAsync<BrowserDimension>("getBrowserDimensions");
    }

}

public class RectDimension
{
    public int Width { get; set; }
    public int Height { get; set; }
}
public class BrowserDimension
{
    public int Width { get; set; }
    public int Height { get; set; }
}

添加到其他服务下的 MyApp/Program.cs

builder.Services.AddScoped<BrowserService>();

MyApp/Pages/Test.razor

@page "/Test"
@using System.Text.Json
@inject BrowserService Browser
@inject IJSRuntime js

<h1>Window Dimensions</h1>


<p>Window Height: @BrowserHeight</p>
<p>Window Width: @BrowserWidth</p>
<p>Box Height: @RectHeight</p>
<p>Box Width: @RectWidth</p>

<button @onclick="GetBrowserDimensions">Get Window Dimensions</button>
<button @onclick="GetRectDimensions">Get Box Dimensions</button>

<h2>Text size: @size</h2>
<div id="box">
    <h2>Text size: @resize</h2>
</div>



@code {
    public decimal size = 1;
    public decimal resize;
    public int RectHeight { get; set; }
    public int RectWidth { get; set; }
    public int BrowserHeight { get; set; }
    public int BrowserWidth { get; set; }

    async Task GetBrowserDimensions()
    {
        var dimension = await Browser.GetBrowserDimensions();
        BrowserHeight = dimension.Height;
        BrowserWidth = dimension.Width;
    }



    public async Task GetRectDimensions()
    {
        Console.WriteLine("starting getRectDimensions");
        var dimensions = await Browser.GetRectDimensions();
        if (dimensions is null) 
        {
            Console.WriteLine("Null Dimensions"); 
        }
        else
        {
            RectHeight = dimensions.Height;
            RectWidth = dimensions.Width;
        }
    }
}

添加到 _framework/blazor.server 下的 MyApp/Pages/_Host.cshtml.js 脚本

    <script type="text/javascript">
        window.getRectDimensions = function () {
            return
            {
                width: document.getElementById("box").getBoundingClientRect().width;
                height: document.getElementById("box").getBoundingClientRect().height;
            }
        };
    </script>
    <script type="text/javascript">
        window.getBrowserDimensions = function () {
            return {
                width: window.innerWidth,
                height: window.innerHeight
            };
        };
    </script>

运行时,“获取窗口尺寸”按钮工作正常,但“获取框尺寸”按钮返回“空尺寸”(如果没有代码块检查空值,它会由于尺寸变量的空值而返回错误)。

我尝试了几种变体,包括将 js 函数“window.getRectDimensions”更改为“getRectDimensions”,以及传递 Blazor ElementReference 而不是使用 Id。

我猜“框”与_Host位于不同的页面上,所以也许 getElementById(“box”) 找不到元素。谁能解释一下这是怎么回事?

我真的不明白 JSInterop 是如何工作的,所以一般的链接或解释会有所帮助,文档对我来说有点高级,我不明白,而大多数教程和指南都是中学生的“hello world”婴儿步骤。我有点需要一个中间的解释。

JavaScript DOM getelementbyid blazor-jsinterop

评论

1赞 Kurt Hamilton 11/10/2023
您没有包含任何 HTML,因此很难知道 id 为“box”的元素在运行时是否存在。在页面上的开发工具控制台中运行时,会得到什么?只要你像对待普通的 JS 一样对待 IJSInterop - 尽管是在全局命名空间中,那么你就不需要深入研究它的内部工作原理(当然,并不是说你不应该选择)。document.getElementById("box")

答:

1赞 Mister Magoo 11/10/2023 #1

除非是错别字,否则您的函数中存在错误 - 宽度和高度之后的分号不应该存在。

试试这个:

window.getRectDimensions = function () {
  return
  {
    width: document.getElementById("box").getBoundingClientRect().width,
    height: document.getElementById("box").getBoundingClientRect().height
  }
};

或更好

window.getRectDimensions = function () {
  let boxRect = document.getElementById("box").getBoundingClientRect();
  return
  {
    width: boxRect.width,
    height: boxRect.height
  }
};