Blazor,如何不断获得当前窗口宽度?
我想在剃须刀页面中这样做:
@if (currentwidth<x)
{
le code
}
else
{
le other code
}
我已添加了Java脚本文件,并将其连接到一个实用程序服务,该实用程序服务在我获得静态宽度(我测试了该宽度)时即可工作。
js:
export function getCurrentWidth() {
return window.addEventListener("resize", () => {
window.innerWidth;
});
}
UtilityService方法:
public async Task<double> GetCurrentWidth()
{
var m = await GetModule();
var result = await m.InvokeAsync<double>("getCurrentWidth");
return result;
}
Razor文件:
double width;
protected async override Task OnInitializedAsync()
{
width = await utilityService.GetCurrentWidth();
}
因此,问题是我不能从OnInitailzedAsync调用它,因为该函数只触发一次,所以我需要一个不断检查GetCurrentWIdth()方法的函数来检查调整大小。
在Blazor中有没有其他方法可以做到这一点,或者我可以使用什么方法/提前谢谢。
解决方案
首先我想指出,您可能不必使用Java脚本/C#代码来解决您的问题。如果您想要操作html中的内容,那么您最好使用css。但我会让你自己决定的。
但是,如果您确实需要如上所述的窗口宽度,那么我建议您向窗口注册一个侦听器(就像您已经做过的那样),并让该侦听器调用一个DotNet函数。使用静态方法实现这一点非常容易,但对于组件来说,这可能会有点棘手,因为您必须传递当前对象的对象引用。[JsInvokable]指示此方法可以从Java脚本调用,这允许从Java脚本事件侦听器到DotNet进行通信。
CSharpFromJs.razor.cs
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using System.Threading.Tasks;
public partial class CSharpFromJS
{
private DotNetObjectReference<CSharpFromJS> _objectReference;
public int WindowWidth { get; set; }
[Inject]
public IJSRuntime JSRuntime { get; set; }
protected override void OnInitialized()
{
_objectReference = DotNetObjectReference.Create(this);
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
await InitWindowWidthListener();
}
}
[JSInvokable]
public void UpdateWindowWidth(int windowWidth)
{
WindowWidth = windowWidth;
StateHasChanged();
}
private async Task InitWindowWidthListener()
{
await JSRuntime.InvokeVoidAsync("AddWindowWidthListener", _objectReference);
}
public async ValueTask DisposeAsync()
{
await JSRuntime.InvokeVoidAsync("RemoveWindowWidthListener", _objectReference);
_objectReference?.Dispose();
}
}
CSharpFromJs.razor
@implements IAsyncDisposable
<h1>Window width: @WindowWidth</h1>
Java脚本
// Manages the registered event listeners so they can be disposed later
let windowEventListeners = {};
function AddWindowWidthListener(objReference) {
let eventListener = () => UpdateWindowWidth(objReference);
window.addEventListener("resize", eventListener);
windowEventListeners[objReference] = eventListener;
}
function RemoveWindowWidthListener(objReference) {
window.removeEventListener("resize", windowEventListeners[objReference]);
}
function UpdateWindowWidth(objReference) {
objReference.invokeMethodAsync("UpdateWindowWidth", window.innerWidth);
}
您唯一需要注意的是组件被释放时。您应该删除DisposeAsync函数中已注册的处理程序,以确保它们不会仍被注册以防止内存泄漏。
This link可能会提供一些有关如何使用它的更好说明,但它们没有解释有关处置处理程序的部分。
注意:这只适用于.net5及更高版本,因为在此之前组件尚未实现IAsyncDisposable。如果出于某种原因您正在使用较早的版本,您可以使用IDisposable调用它。但这可能会导致死锁,因此我不建议您这样做。
相关文章