簡體   English   中英

使用 Javascript 獲取 Blazor 頁面的大小

[英]Getting the size of a Blazor page with Javascript

我正在學習 Blazor 的 JSInterop。我想獲得 Blazor 頁面的寬度和高度,大小為 à canvas。

我正在使用默認的 Blazor 模板和屏幕左側的菜單欄。 在此處輸入圖像描述

在 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.innerWidthdocument.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM