【问题标题】:How do i subscribe to onscroll event in Blazor?如何在 Blazor 中订阅 onscroll 事件?
【发布时间】:2020-07-28 13:44:27
【问题描述】:

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

【问题讨论】:

  • 至少应该通过 js interop 工作。如果没有,您的代码中有错误

标签: header blazor parallax onscroll


【解决方案1】:

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

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;
    }
}

【讨论】:

    【解决方案2】:

    这是通过evalmyDiv div 获取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 here 上查看它的实际效果 - 在这里您需要将 JS 自定义函数 getScrollToTop 添加到 DOM window 对象:

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

    并以这种方式调用它:

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

    【讨论】:

      【解决方案3】:

      您只需创建一个 Razor 页面,即可轻松处理 Blazor OnScroll 事件,其工作方式如下:

      @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++;
          }
      
      }

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-02-04
        • 1970-01-01
        • 2013-11-03
        • 1970-01-01
        • 2010-09-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多