有没有办法检测用户何时关闭 Blazor Server 中的浏览器?
您需要在浏览器 beforeunload 事件上设置侦听器以回调到 Blazor。
首先是一些JS。
// site.js
// load in _Layout_.cshtml
window.blazr_setExitCheck = function (dotNetHelper, set) {
if (set) {
window.addEventListener("beforeunload", blazr_spaExit);
blazrDotNetExitHelper = dotNetHelper;
}
else {
window.removeEventListener("beforeunload", blazr_spaExit);
blazrDotNetExitHelper = null;
}
}
var blazrDotNetExitHelper;
window.blazr_spaExit = function (event) {
event.preventDefault();
blazrDotNetExitHelper.invokeMethodAsync("SpaExit");
}
站点退出服务。您可以在SpaExit 中运行任何您想要的代码,或者在SPAClosed 中从其他地方注册一个事件处理程序。
public class SiteExitService
{
private IJSRuntime? _js { get; set; }
private TaskCompletionSource? _taskCompletionSource;
public event EventHandler? SPAClosed;
public SiteExitService(IJSRuntime? js)
=> _js = js;
public async Task SetSpaExit()
{
// makes sure we only do it once
if (_taskCompletionSource is null)
{
_taskCompletionSource = new TaskCompletionSource();
var objref = DotNetObjectReference.Create(this);
await _js!.InvokeVoidAsync("blazr_setExitCheck", objref, true);
_taskCompletionSource.SetResult();
}
if (!_taskCompletionSource.Task.IsCompleted)
await _taskCompletionSource.Task;
}
[JSInvokable]
public Task SpaExit()
{
// do whatever you want to do on exit Raise an event if you wish
this.SPAClosed?.Invoke(null, EventArgs.Empty);
return Task.CompletedTask;
}
}
程序:
// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
builder.Services.AddSingleton<WeatherForecastService>();
builder.Services.AddScoped<SiteExitService>();
在 App 中设置,以便始终加载。
// <Router AppAssembly="@typeof(App).Assembly">
// ...
//</Router>
@code {
[Inject] private SiteExitService Service { get; set; } = default!;
protected async override Task OnAfterRenderAsync(bool firstRender)
=> await Service.SetSpaExit();
}
通过在 this.SPAClosed?.Invoke(null, EventArgs.Empty); 上放置断点来检查它是否有效。