如何订阅Blazor的onscroll活动



我正试图对Blazor中的onscroll事件做出反应,以便在用户向下滚动网页时为图像设置动画(类似于本网站上的品牌标志:https://lebenswelten-stgabriel.at/)。我尝试过本机的onscroll事件,也尝试过使用jsinterop,但它没有任何作用。这是Blazor中目前不可用的东西吗?还是我只是在听错误组件上的滚动事件?

经过几次尝试和错误之后,我决定创建一个在js端注册的自定义.net服务。该服务看起来像这样:

using System;
using Microsoft.JSInterop;
namespace myBlazorApp.Services
{
public class ScrollInfoService: IScrollInfoService
{
public event EventHandler<int> OnScroll; 
public ScrollInfoService(IJSRuntime jsRuntime)
{
RegisterServiceViaJsRuntime(jsRuntime);
}
private void RegisterServiceViaJsRuntime(IJSRuntime jsRuntime)
{
jsRuntime.InvokeVoidAsync("RegisterScrollInfoService", DotNetObjectReference.Create(this));
}
public int YValue { get; private set; }
[JSInvokable("OnScroll")]
public void JsOnScroll(int yValue)
{
YValue = yValue;
Console.WriteLine("ScrollInfoService.OnScroll " + yValue);
OnScroll?.Invoke(this, yValue);
}
}
public interface IScrollInfoService
{
event EventHandler<int> OnScroll; 
int YValue { get; }
}
}

该服务从DOM接收onscroll事件,并在.net端引发一个事件。以下是脚本在js端的样子:

window.onscroll = function() {
if (window.scrollInfoService != null)
window.scrollInfoService.invokeMethodAsync('OnScroll', window.pageYOffset);
}
window.RegisterScrollInfoService = (scrollInfoService) => {
window.scrollInfoService = scrollInfoService;
}

然后,我将我的服务注入到任何需要它的Blazor组件中,如下所示:

@using myBlazorApp.Services
@inject IScrollInfoService scrollInfoService
@implements IDisposable
<div>
...
</div>
@code {
protected override void OnInitialized()
{
scrollInfoService.OnScroll += OnScroll;
}
private void OnScroll(object sender, int yValue)
{
DoSomething(yValue);
}
public void Dispose()
{
scrollInfoService.OnScroll -= OnScroll;
}
}

这是如何通过evalmyDivdiv获取scrollTop(奇怪但有效(-请参阅Blazor REPL上的操作。

@inject IJSRuntime JSRuntime;
<h1>DIV scrollTop: @ScrollTop</h1> 
<div id="myDiv" style="overflow:scroll; height:400px;" @onscroll="@OnScroll" >

<p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p>
<p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p>
<p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p>
<p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p>
<p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p>
<p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p>
</div>
@code {
public int ScrollTop { get; set; }
private async Task OnScroll(EventArgs e)
{
ScrollTop = await JSRuntime.InvokeAsync<int>(
"eval", "document.getElementById('myDiv').scrollTop");
}
}

更新:类似的方法,但不使用eval-感谢Kristian Mariyanov。在这里查看Blazor REPL上的操作-在这里您需要将JS自定义函数getScrollToTop添加到DOMwindow对象:

<script>
window.getScrollToTop =  (selector) => {
return document.querySelector(selector).scrollTop
}
</script>

并以这种方式调用它:

ScrollTop = await JS.InvokeAsync<int>("getScrollToTop", "#myDiv");

只需创建一个Razor页面,就可以轻松处理BlazorOnScroll事件,其工作方式如下:

@page "/ScrollTest"
<h3>Scrolling</h3>
<div class="scroll" @onscroll="OnScroll">
fdsgdf qsdfsqdf sqfgdsfgdfg rtg ret rez
fdsgdf qsdfsqdf sqfgdsfgdfg rtg ret rez
fdsgdf qsdfsqdf sqfgdsfgdfg rtg ret rez
fdsgdf qsdfsqdf sqfgdsfgdfg rtg ret rez
fdsgdf qsdfsqdf sqfgdsfgdfg rtg ret rez
fdsgdf qsdfsqdf sqfgdsfgdfg rtg ret rez
fdsgdf qsdfsqdf sqfgdsfgdfg rtg ret rez
fdsgdf qsdfsqdf sqfgdsfgdfg rtg ret rez
fdsgdf qsdfsqdf sqfgdsfgdfg rtg ret rez
fdsgdf qsdfsqdf sqfgdsfgdfg rtg ret rez
fdsgdf qsdfsqdf sqfgdsfgdfg rtg ret rez
fdsgdf qsdfsqdf sqfgdsfgdfg rtg ret rez
fdsgdf qsdfsqdf sqfgdsfgdfg rtg ret rez
fdsgdf qsdfsqdf sqfgdsfgdfg rtg ret rez
fdsgdf qsdfsqdf sqfgdsfgdfg rtg ret rez
fdsgdf qsdfsqdf sqfgdsfgdfg rtg ret rez
fdsgdf qsdfsqdf sqfgdsfgdfg rtg ret rez
fdsgdf qsdfsqdf sqfgdsfgdfg rtg ret rez
fdsgdf qsdfsqdf sqfgdsfgdfg rtg ret rez
fdsgdf qsdfsqdf sqfgdsfgdfg rtg ret rez
fdsgdf qsdfsqdf sqfgdsfgdfg rtg ret rez
fdsgdf qsdfsqdf sqfgdsfgdfg rtg ret rez
fdsgdf qsdfsqdf sqfgdsfgdfg rtg ret rez
fdsgdf qsdfsqdf sqfgdsfgdfg rtg ret rez
</div>
<div class="m-2 p-2">Scroll events: @counter</div>

<style>
div.scroll {
margin: 4px, 4px;
padding: 4px;
width: 500px;
height: 110px;
overflow-x: hidden;
overflow-y: auto;
text-align: justify;
}
</style>
@code {
private int counter;
private void OnScroll()
{
counter++;
}
}

相关内容

  • 没有找到相关文章

最新更新