[英]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.