2

I got a javascript observer in my Blazor-App. (while scrolling it is detecting a GUI-item on the lower end of the scrolled list to load following items. -> paging, lazy load) This listener is subscribed one time, I checked by breakpoint. But each time the observer is activated it is firing two times instead of one time. I can't figure out why I get the event two times. Could it be it is firing when it gets into the view and again when it is leaving the view?

Do you have a idea, why OnIntersectionSearch() is called always two times and how to avoid it?

JavaScript:

window.ObserverSearch = {
  observer: null,
    Initialize: function (component, observerId) {
      this.observer = new IntersectionObserver(e => {
        component.invokeMethodAsync('OnIntersectionSearch');
      });

      let element = document.getElementById(observerId);
      if (element == null) throw new Error("Target was not found");
      this.observer.observe(element);
  }
};

Blazor component InfiniteScrollSearch.razor

@inject IJSRuntime JSRuntime
@ChildContent

InfiniteScrollSearch.razor.cs

public partial class InfiniteScrollSearch
{
    [Parameter]
    public RenderFragment? ChildContent { get; set; }

    [Parameter]
    public string? ObserverSearchTarget { get; set; }

    [Parameter]
    public EventCallback<bool> ObservableSearchEndReached { get; set; }

    private DotNetObjectReference<InfiniteScrollSearch>? _objectRef;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            _objectRef = DotNetObjectReference.Create(this);
            await JSRuntime.InvokeAsync<dynamic>("ObserverSearch.Initialize", _objectRef, ObserverSearchTarget);
        }
    }

    [JSInvokable]
    public async Task OnIntersectionSearch()
    {
        // this is always to times called
        await ObservableSearchEndReached.InvokeAsync(true);
    }
}
Frank Mehlhop
  • 1,480
  • 4
  • 25
  • 48

2 Answers2

0

have a look at this. It solves the problem.

The reference code, you have to refer to is:

<button @ref="myButton" id="counterClick" class="btn btn-primary counterClickC" @onclick="IncrementCount">Click me</button>

@code {
    private ElementReference myButton;

    protected async override Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            await js.InvokeVoidAsync("initializeCounterComponent", myButton);
        }
    }
}
Code4Fun
  • 413
  • 5
  • 17
0

went into similar problem like you and found solution here:

IntersectionObserver isIntersecting property never is false if threshold greater than 0

Modify your js like that:

window.Observer = {
    observer: null,
    Initialize: function (component, observerTargetId) {

        this.observer = new IntersectionObserver(entries => {
            
            entries
                .forEach(entry => {
                    if (entry.intersectionRatio === 1) {
                        console.log(entry.target.id, "is fully visible");
                        component.invokeMethodAsync('OnIntersection');
                    } else if (!entry.isIntersecting) {
                        console.log(entry.target.id, "has left the viewport")
                    } else if (entry.intersectionRatio > 0.5) {
                        var ratio = entry.intersectionRatio.toFixed(4);
                        console.log(entry.target.id, "has started leaving the viewport (ratio " + ratio + ")");
                    } else if (entry.intersectionRatio < 0.5) {
                        var ratio = entry.intersectionRatio.toFixed(4);
                        console.log(entry.target.id, "has started entering the viewport (ratio " + ratio + ")");
                    }
                });

        });

        var element = document.getElementById(observerTargetId);
        if (element == null) throw new Error("Target was not found");
        this.observer.observe(element);
    }
};

For me worked the best placing component.invokeMethodAsync into first if. But you can try other blocks if not working well for you. Hope this helps.

Hellis
  • 3
  • 4