[英]Getting the size of a Blazor page with Javascript
我正在学习 Blazor 的 JSInterop。我想获得 Blazor 页面的宽度和高度,大小为 à canvas。
在 Canvas 测试 1 页的 html 部分,我有:
@page "/canvas_test1"
@inject IJSRuntime JsRuntime
<canvas @ref="canvas1"></canvas>
<button @onclick="SetCanvasSize">Set canvas size</button>
在代码部分我有:
ElementReference canvas1;
async Task SetCanvasSize()
{
await JsRuntime.InvokeVoidAsync("SetCanvasSize", canvas1);
}
在 Javascript 文件中,我有:
function SetCanvasSize(element) {
ctx = element.getContext('2d');
console.log(window.innerWidth);
console.log(document.documentElement.scrollWidth);
}
但是window.innerWidth和document.documentElement.scrollWidth这两种方法都给出了整个 window 的宽度,而不仅仅是包含 canvas 的页面。
如何在没有侧面菜单的情况下仅获取页面的宽度?
谢谢
我认为您对 Blazor 中的页面是什么感到有点困惑。它基本上是您提供导航路径的组件。 如果您包括布局(通常默认设置),那实际上是页面的一部分。 页面上的所有内容,例如您的 canvas,都只是 html 个元素。 它正确地告诉您 window 的大小,如果您调整浏览器的大小,您可以看到它会发生变化。
html 元素具有属性“offsetWidth”和“offsetHeight”。 因此,为了您的使用,您想要传递要测量的元素,并使用element.offsetWidth
:
function GetCanvasSize(element) {
alert ("Element measurements: " + element.offsetWidth + ", " + element.offsetHeight);
}
你可以在这里看到html元素的更多成员,包括常用的方法和事件: https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetWidth
请注意,此列表缺少您想要了解的一些重要信息,尤其是您在移动客户端上拖动元素所需的各种触摸事件(鼠标事件在手机上不起作用)。
您需要获取包含元素的尺寸。 您还需要监听调整大小事件。
我使用的服务可以为任何元素获取 ref 并监听更改。
bCore.js
export function listenToWindowResize(dotNetHelper) {
function resizeEventHandler() {
dotNetHelper.invokeMethodAsync('WindowResizeEvent');
}
window.addEventListener("resize", resizeEventHandler);
dotNetHelper.invokeMethodAsync('WindowResizeEvent');
}
export function getBoundingRectangle(element, parm) {
return element.getBoundingClientRect();
}
export function getWindowSizeDetails(parm) {
var e = window, a = 'inner';
if (!('innerWidth' in window)) {
a = 'client';
e = document.documentElement || document.body;
}
let windowSize =
{
innerWidth: e[a + 'Width'],
innerHeight: e[a + 'Height'],
screenWidth: window.screen.width,
screenHeight: window.screen.height
};
return windowSize;
}
JSInteropCoreService.cs
public class JSInteropCoreService : IJSInteropCoreService, IAsyncDisposable
{
private readonly Lazy<Task<IJSObjectReference>> moduleTask;
private bool isResizing;
private System.Timers.Timer resizeTimer;
private DotNetObjectReference<JSInteropCoreService> jsInteropCoreServiceRef;
public JSInteropCoreService(IJSRuntime jsRuntime)
{
this.resizeTimer = new System.Timers.Timer(interval: 25);
this.isResizing = false;
this.resizeTimer.Elapsed += async (sender, elapsedEventArgs) => await DimensionsChanged(sender!, elapsedEventArgs);
this.moduleTask = new(() => jsRuntime.InvokeAsync<IJSObjectReference>(
identifier: "import", args: "./_content/BJSInteroptCore/bCore.js").AsTask());
}
public event NotifyResizing OnResizing;
public event NotifyResize OnResize;
public async ValueTask InitializeAsync()
{
IJSObjectReference module = await GetModuleAsync();
this.jsInteropCoreServiceRef = DotNetObjectReference.Create(this);
await module.InvokeVoidAsync(identifier: "listenToWindowResize", this.jsInteropCoreServiceRef);
this.BrowserSizeDetails = await module.InvokeAsync<BrowserSizeDetails>(identifier: "getWindowSizeDetails");
}
public async ValueTask<BrowserSizeDetails> GetWindowSizeAsync()
{
IJSObjectReference module = await GetModuleAsync();
return await module.InvokeAsync<BrowserSizeDetails>(identifier: "getWindowSizeDetails");
}
public async ValueTask<ElementBoundingRectangle> GetElementBoundingRectangleAsync(ElementReference elementReference)
{
IJSObjectReference module = await GetModuleAsync();
return await module.InvokeAsync<ElementBoundingRectangle>(identifier: "getBoundingRectangle", elementReference);
}
[JSInvokable]
public ValueTask WindowResizeEvent()
{
if (this.isResizing is not true)
{
this.isResizing = true;
OnResizing?.Invoke(this.isResizing);
}
DebounceResizeEvent();
return ValueTask.CompletedTask;
}
public BrowserSizeDetails BrowserSizeDetails { get; private set; } = new BrowserSizeDetails();
private void DebounceResizeEvent()
{
if (this.resizeTimer.Enabled is false)
{
Task.Run(async () =>
{
this.BrowserSizeDetails = await GetWindowSizeAsync();
isResizing = false;
OnResizing?.Invoke(this.isResizing);
OnResize?.Invoke();
});
this.resizeTimer.Restart();
}
}
private async ValueTask DimensionsChanged(object sender, System.Timers.ElapsedEventArgs e)
{
this.resizeTimer.Stop();
this.BrowserSizeDetails = await GetWindowSizeAsync();
isResizing = false;
OnResizing?.Invoke(this.isResizing);
OnResize?.Invoke();
}
public async ValueTask DisposeAsync()
{
if (moduleTask.IsValueCreated)
{
IJSObjectReference module = await GetModuleAsync();
await module.DisposeAsync();
}
}
private async Task<IJSObjectReference> GetModuleAsync()
=> await this.moduleTask.Value;
}
public class ElementBoundingRectangle
{
public double X { get; set; }
public double Y { get; set; }
public double Width { get; set; }
public double Height { get; set; }
public double Top { get; set; }
public double Right { get; set; }
public double Bottom { get; set; }
public double Left { get; set; }
}
public class BrowserSizeDetails
{
public double InnerWidth { get; set; }
public double InnerHeight { get; set; }
public int ScreenWidth { get; set; }
public int ScreenHeight { get; set; }
}
我使用 25 毫秒的间隔对调整大小事件进行去抖动以防止延迟。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.