Blazor JSInterop Getting Element Attributes from the DOM

194 views Asked by At

I've made a Blazor Serverside Web App using the Visual Studio 2022 boilerplate project. I am still using .NET 7 as my company is slow to do updates.

I have followed this tutorial on using the JSInterop to get the dimensions of the window from the DOM. I then tried adjusting the code to get the dimensions of a particular element. I have the following files:

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; }
}

Added to MyApp/Program.cs under the other services

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;
        }
    }
}

Added To MyApp/Pages/_Host.cshtml under the _framework/blazor.server.js Script

    <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>

When run, the "Get Window Dimensions" Button works fine but the "Get Box Dimensions" button returns "Null Dimensions" (without the code block checking for null, it returns an error due to the null value of the dimensions variable).

I have tried several variations, including changing the js function "window.getRectDimensions" to just "getRectDimensions", and passing a Blazor ElementReference instead of using an Id.

I'm guessing that the "box" is on a different page than the _Host so maybe getElementById("box") can't find the element. Can anyone explain what's going on here?

I really don't understand how the JSInterop works, so general links or explanations would be helpful, the documentation is a bit advanced for me and I don't understand it, while most tutorials and guides are "hello world" baby steps for middle-schoolers. I kinda need an intermediate explanation.

1

There are 1 answers

0
Mister Magoo On

Unless it is a typo, you have an error in your function - semicolons after width and height should not be there.

Try this:

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

or better

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